From 3349ba9cbf4462e3914ed198857476eb3c1a0525 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Mon, 21 Aug 2023 17:59:22 -0400 Subject: [PATCH 01/52] Start of uTransport Does not compile, only pushing to temp for now --- .../utransport/CloudEventUMessage.java | 72 +++++ .../utransport/CloudEventUMessageParser.java | 104 +++++++ .../uprotocol/utransport/EmptyUMessage.java | 76 +++++ .../uprotocol/utransport/MessageType.java | 44 +++ .../uprotocol/utransport/Priority.java | 58 ++++ .../utransport/SerializationHint.java | 47 ++++ .../uprotocol/utransport/SimpleUMessage.java | 98 +++++++ .../eclipse/uprotocol/utransport/Status.java | 119 ++++++++ .../uprotocol/utransport/UAttributes.java | 261 ++++++++++++++++++ .../uprotocol/utransport/UListener.java | 18 ++ .../uprotocol/utransport/UMessage.java | 35 +++ .../uprotocol/utransport/UPayload.java | 89 ++++++ .../eclipse/uprotocol/utransport/UTopic.java | 55 ++++ .../uprotocol/utransport/UTransport.java | 65 +++++ 14 files changed, 1141 insertions(+) create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/MessageType.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/Priority.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/Status.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UListener.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UMessage.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UPayload.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UTopic.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UTransport.java diff --git a/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java new file mode 100644 index 00000000..75dd48d5 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java @@ -0,0 +1,72 @@ +package org.eclipse.uprotocol.utransport; + + +import java.util.Objects; + +/** + * An implementation of a UMessage mapping from a CloudEvent. + */ +public class CloudEventUMessage extends SimpleUMessage implements UMessage { + + private final static Logger logger = LoggerFactory.getLogger(CloudEventUMessage.class); + + private final CloudEvent cloudEvent; + + private CloudEventUMessage(String id, UTopic source, UPayload payload, int priority, CloudEvent cloudEvent) { + super(id, source, payload, priority); + this.cloudEvent = cloudEvent; + } + + public static CloudEventUMessage fromCloudEvent(CloudEvent cloudEvent) { + logger.info("ce [{}]", cloudEvent); + CloudEvent ce; + if (cloudEvent == null) { + logger.info("ce is null"); + ce = CloudEventFactory.publish("ultifi:/", Any.getDefaultInstance(), UCloudEventAttributes.empty()); + } else { + ce = cloudEvent; + } + final UltifiUri ultifiUri = UltifiUriFactory.parseFromUri(UCloudEvent.getSource(ce)); + final Any cePayload = UCloudEvent.getPayload(ce); + final String cePriority = UCloudEvent.getPriority(ce) + .orElseGet(UCloudEventAttributes.Priority.LOW::qosString); + return new CloudEventUMessage(ce.getId(), + new UTopic(ultifiUri.uAuthority(), ultifiUri.uEntity(), ultifiUri.uResource()), + UPayload.fromProtoBytesofTypeAny(cePayload.toByteArray()), + calculatePriority(cePriority), + ce); + } + + public static int calculatePriority(String qosString) { + return Integer.parseInt(qosString.replace("CS", "")); + } + + public static CloudEventUMessage empty() { + return fromCloudEvent(null); + } + + public CloudEvent cloudEvent() { + return this.cloudEvent; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + CloudEventUMessage that = (CloudEventUMessage) o; + return Objects.equals(cloudEvent, that.cloudEvent); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), cloudEvent); + } + + @Override + public String toString() { + return "CloudEventUMessage{" + + "cloudEvent=" + cloudEvent + + "} " + super.toString(); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java b/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java new file mode 100644 index 00000000..1a305d9e --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java @@ -0,0 +1,104 @@ +package org.eclipse.uprotocol.utransport; + +import java.net.URI; +import java.util.Optional; + +/** + * Parsing to and from the CloudEvent PDU - protocol data unit, a.k.a the requestRpcMessage envelope/object that contains the data & metadata. + * //TODO need to figure out attributes and other aspects of building the correct CloudEvent + * //TODO how to handle errors? I don't like exceptions very much. Sending something invalid over the wire is yucky as well. + */ +public record CloudEventUMessageParser() { + + private static final Logger logger = LoggerFactory.getLogger(CloudEventUMessageParser.class); + private static final String NONE = "NONE"; + + public static UMessage toUMessage(CloudEvent cloudEvent) { + logger.info("processing CloudEvent [{}]", cloudEvent); + if (cloudEvent == null) { + logger.info("CloudEvent is null"); + return SimpleUMessage.empty(); + } + final UltifiUri cloudEventsourceUri = UltifiUriFactory.parseFromUri(UCloudEvent.getSource(cloudEvent)); + final Any cePayload = UCloudEvent.getPayload(cloudEvent); + final String cloudEventType = cloudEvent.getType(); + final Optional maybeSink = UCloudEvent.getSink(cloudEvent); + if (UCloudEventType.REQUEST.type().equals(cloudEventType)) { + if (maybeSink.isPresent()) { + UltifiUri sink = UltifiUriFactory.parseFromUri(maybeSink.get()); + return RpcUMessage.buildRpcRequest(cloudEvent.getId(), + new UTopic(cloudEventsourceUri.uAuthority(), cloudEventsourceUri.uEntity(), cloudEventsourceUri.uResource()), + new UTopic(sink.uAuthority(), sink.uEntity(), sink.uResource()), + UPayload.fromProtoBytesofTypeAny(cePayload.toByteArray())); + } + } else if (UCloudEventType.RESPONSE.type().equals(cloudEventType)) { + if (maybeSink.isPresent()) { + UltifiUri sink = UltifiUriFactory.parseFromUri(maybeSink.get()); + return RpcUMessage.buildRpcResponse(cloudEvent.getId(), + new UTopic(sink.uAuthority(), sink.uEntity(), sink.uResource()), + new UTopic(cloudEventsourceUri.uAuthority(), cloudEventsourceUri.uEntity(), cloudEventsourceUri.uResource()), + UCloudEvent.getRequestId(cloudEvent).orElse(NONE), + UPayload.fromProtoBytesofTypeAny(cePayload.toByteArray())); + } + } + return CloudEventUMessage.fromCloudEvent(cloudEvent); + } + + public static CloudEvent toCloudEvent(UMessage uMessage) { + logger.info("building CloudEvent from [{}]", uMessage); + final UTopic sourceTopic = uMessage.source(); + String uMessageSource = UltifiUriFactory.buildUProtocolUri(sourceTopic.uAuthority(), + sourceTopic.uEntity(), sourceTopic.uResource()); + Any protoPayload = getProtoPayloadFromMessage(uMessage); + + if (uMessage instanceof RpcUMessage rpcUMessage) { + final boolean isRequest = rpcUMessage.isRPCRequest(); + final UTopic sinkTopic = rpcUMessage.sink(); + String serviceMethodForUri = UltifiUriFactory.buildUProtocolUri(sinkTopic.uAuthority(), + sinkTopic.uEntity(), sinkTopic.uResource()); + if (isRequest) { + return CloudEventFactory.buildBaseCloudEvent(rpcUMessage.id(), uMessageSource, + protoPayload.toByteArray(), protoPayload.getTypeUrl(), + UCloudEventAttributes.empty()) + .withType(UCloudEventType.REQUEST.type()) + .withExtension("sink", serviceMethodForUri) + .build(); + } else { + return CloudEventFactory.buildBaseCloudEvent(rpcUMessage.id(), serviceMethodForUri, + protoPayload.toByteArray(), protoPayload.getTypeUrl(), + UCloudEventAttributes.empty()) + .withType(UCloudEventType.RESPONSE.type()) + .withExtension("sink", URI.create(uMessageSource)) + .withExtension("reqid", rpcUMessage.requestId().orElse(NONE)) + .build(); + } + } + if (uMessage instanceof CloudEventUMessage cloudEventUMessage) { + logger.info("building CloudEventUMessage"); + return cloudEventUMessage.cloudEvent(); + } + if (uMessage instanceof SimpleUMessage) { + return CloudEventFactory.publish(uMessageSource, protoPayload, UCloudEventAttributes.empty()); + } + logger.error("building base cloud event since we don't know what we have"); + // we don't really know what we have, so build something + return CloudEventFactory.buildBaseCloudEvent( + CloudEventFactory.generateTimeOrderedCloudEventId(), + uMessageSource, + protoPayload.toByteArray(), + protoPayload.getTypeUrl(), + UCloudEventAttributes.empty()) + .build(); + } + + private static Any getProtoPayloadFromMessage(UMessage uMessage) { + try { + return Any.parseFrom(uMessage.payload().data()); + } catch (InvalidProtocolBufferException e) { + logger.error("Unable to build the CloudEvent payload since we can't parse the Payload into an Any object."); + return Any.getDefaultInstance(); + //throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java new file mode 100644 index 00000000..c1993fd7 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java @@ -0,0 +1,76 @@ +package org.eclipse.uprotocol.utransport; + +import java.util.Objects; +import java.util.UUID; + +/** + * Class for returning new Empty Messages. This can be useful to return empty values in cases where there are + * errors. The requestRpcMessage still has a unique identifier for tracing but is empty since there is nothing to add since there was an error. + * TODO check if this is needed, or use a simple requestRpcMessage with empty + */ +public class EmptyUMessage implements UMessage { + + private final String id; + + /** + * Construct an EmptyUMessage. + * @param id Unique identifier of the requestRpcMessage. + */ + public EmptyUMessage(String id) { + this.id = id; + } + + public EmptyUMessage() { + this(UUID.randomUUID().toString()); + } + + @Override + public String id() { + return this.id; + } + + @Override + public UTopic source() { + return UTopic.empty(); + } + + @Override + public UPayload payload() { + return UPayload.empty(); + } + + @Override + public boolean isExpired() { + return false; + } + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public String toLog() { + return toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EmptyUMessage that = (EmptyUMessage) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "EmptyUMessage{" + + "id='" + id + '\'' + + '}'; + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/MessageType.java b/src/main/java/org/eclipse/uprotocol/utransport/MessageType.java new file mode 100644 index 00000000..017fc9df --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/MessageType.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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. + */ + + package org.eclipse.uprotocol.utransport; + +public enum MessageType { + PUBLISH(0, "pub.v1"), // Publish or notification event + REQUEST(1, "req.v1"), // Request + RESPONSE(2, "res.v1"); // Response + + private final int value; + private final String name; + + public int typeValue() { + return value; + } + + public String typeName() { + return name; + } + + MessageType(int value, String name) { + this.value = value; + this.name = name; + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/Priority.java b/src/main/java/org/eclipse/uprotocol/utransport/Priority.java new file mode 100644 index 00000000..66d7b483 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/Priority.java @@ -0,0 +1,58 @@ +package org.eclipse.uprotocol.utransport; + +import java.util.Arrays; +import java.util.Optional; + +public enum Priority { + // Low Priority. No bandwidth assurance such as File Transfer. + LOW ("CS0", 0), + // Standard, undifferentiated application such as General (unclassified). + STANDARD ("CS1", 1), + // Operations, Administration, and Management such as Streamer messages (sub, connect, etc…) + OPERATIONS ("CS2", 2), + // Multimedia streaming such as Video Streaming + MULTIMEDIA_STREAMING ("CS3", 3), + // Real-time interactive such as High priority (rpc events) + REALTIME_INTERACTIVE ("CS4", 4), + // Signaling such as Important + SIGNALING("CS5", 5), + // Network control such as Safety Critical + NETWORK_CONTROL ("CS6", 6); + + private final String qosString; + private final int value; + public String qosString() { + return qosString; + } + + public int intValue() { + return value; + } + + Priority(String qosString, int value) { + this.qosString = qosString; + this.value = value; + } + + /** + * Find the Priority matching the numeric value. Mind you, it might not exist. + * @param value numeric priority value. + * @return Returns the Priority matching the numeric value. Mind you, it might not exist. + */ + public static Optional from(int value) { + return Arrays.stream(Priority.values()) + .filter(p -> p.intValue() == value) + .findAny(); + } + + /** + * Find the Priority matching the QOS String value. Mind you, it might not exist. + * @param qosString QOS String priority value. + * @return Returns the Priority matching the QOS String value. Mind you, it might not exist. + */ + public static Optional from(String qosString) { + return Arrays.stream(Priority.values()) + .filter(p -> p.qosString().equals(qosString)) + .findAny(); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java b/src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java new file mode 100644 index 00000000..e0d03136 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport; + +public enum SerializationHint { + UNKNOWN(0, ""), + PROTOBUF (1, "application/x-protobuf"), // data is a Base64 encoded protobuf string + JSON(2, "application/json"), // data is a UTF-8 string containing a JSON structure + SOMEIP(3, "application/x-someip"), // data is a UTF-8 string containing a JSON structure + RAW(4, "application/octet-stream"); // data is a Base64 encoded protobuf string of an Any object with the payload inside + + private final int hintNumber; + private final String mimeType; + + public int hintNumber() { + return hintNumber; + } + + public String mimeType() { + return mimeType; + } + + SerializationHint(int hintNumber, String mimeType) { + this.hintNumber = hintNumber; + this.mimeType = mimeType; + } +} + diff --git a/src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java new file mode 100644 index 00000000..47c723f7 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java @@ -0,0 +1,98 @@ +package com.eclipse.uprotocol.uhello.akkaapp.sdk.umessage; + +import java.util.Objects; +import java.util.UUID; + +/** + * The most basic representation of a UMessage. + */ +public class SimpleUMessage implements UMessage { + + private static final SimpleUMessage EMPTY = new SimpleUMessage(null, UTopic.empty(), UPayload.empty(), 0); + + private final String Id; + private final UTopic source; + private final UPayload payload; + private final int priority; + + /** + * Create a simple UMessage. + * @param id Unique identifier of the requestRpcMessage. + * @param source The definition of the software where this requestRpcMessage originated, or the requester of an RPC. + * @param payload The actual raw bytes or serialized bytes containing the payload of the requestRpcMessage. + * @param priority some priority...? + */ + public SimpleUMessage(String id, UTopic source, UPayload payload, int priority) { + Id = Objects.requireNonNullElseGet(id, () -> UUID.randomUUID().toString()); + this.source = Objects.requireNonNullElseGet(source, UTopic::empty); + this.payload = Objects.requireNonNullElseGet(payload, UPayload::empty); + this.priority = priority; + } + + public SimpleUMessage(String id, UTopic source, UPayload payload) { + this(id, source, payload, 0); + } + + public SimpleUMessage(UTopic source, UPayload payload) { + this(null, source, payload, 0); + } + + public static SimpleUMessage empty() { + return EMPTY; + } + + @Override + public String id() { + return this.Id; + } + + @Override + public UTopic source() { + return this.source; + } + + @Override + public UPayload payload() { + return this.payload; + } + + @Override + public boolean isExpired() { + // since there is no ttl, this requestRpcMessage never expires. + return false; + } + + @Override + public boolean isEmpty() { + return this.source.isEmpty() && this.payload.isEmpty(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SimpleUMessage that = (SimpleUMessage) o; + return priority == that.priority && Objects.equals(Id, that.Id) + && Objects.equals(source, that.source) && Objects.equals(payload, that.payload); + } + + @Override + public int hashCode() { + return Objects.hash(Id, source, payload, priority); + } + + @Override + public String toString() { + return "SimpleUMessage{" + + "Id='" + Id + '\'' + + ", source=" + source + + ", payload=" + payload + + ", priority=" + priority + + '}'; + } + + public String toLog() { + return String.format("Id=%s, source=%s, priority=%s", + id(), source().toLog(), priority); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/Status.java b/src/main/java/org/eclipse/uprotocol/utransport/Status.java new file mode 100644 index 00000000..26e74c96 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/Status.java @@ -0,0 +1,119 @@ +package org.eclipse.uprotocol.utransport; + +import java.util.Objects; + +/** + * UProtocol general Ack requestRpcMessage for all operations. + * Can be made into a Monad in the future. + */ +public abstract class Status { + + private static final String OK = "ok"; + private static final String FAILED = "failed"; + + public abstract boolean isSuccess(); + public abstract String msg(); + + public boolean isFailed() { + return !isSuccess(); + } + + @Override + public String toString() { + return String.format("Ack %s %s %s", isSuccess() ? "ok" : "failed", + isSuccess() ? "id =" : "msg=", msg()); + } + + private static class OKSTATUS extends Status { + + /** + * A successful Ack can contain an id for tracking purposes. + */ + private final String id; + + private OKSTATUS(String id) { + this.id = id; + } + + @Override + public boolean isSuccess() { + return true; + } + + @Override + public String msg() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OKSTATUS okstatus = (OKSTATUS) o; + return Objects.equals(id, okstatus.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + } + private static class FAILSTATUS extends Status { + + private final String failMsg; + + // TODO make this into an Enum so Steven does not loose his panties + private final int failureReason; + + private FAILSTATUS(String failMsg, int failureReason) { + this.failMsg = failMsg; + this.failureReason = failureReason; + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public String msg() { + return this.failMsg; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FAILSTATUS failstatus = (FAILSTATUS) o; + return failureReason == failstatus.failureReason && Objects.equals(failMsg, failstatus.failMsg); + } + + @Override + public int hashCode() { + return Objects.hash(failMsg, failureReason); + } + + } + + public static Status ok() { + return new OKSTATUS(Status.OK); + } + + public static Status ok(String ackId) { + return new OKSTATUS(ackId); + } + + public static Status failed() { + return new FAILSTATUS(FAILED, 0); + } + + public static Status failed(String msg) { + return new FAILSTATUS(msg, 0); + } + + public static Status failed(String msg, int failureReason) { + return new FAILSTATUS(msg, failureReason); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java new file mode 100644 index 00000000..bf973bb6 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport; + +import java.util.Objects; +import java.util.Optional; + +public class UAttributes { + + private static final UAttributes EMPTY = new UAttributes(null, null, null, null, null, null, null); + + private final String hash; + private final Priority priority; + private final Integer ttl; + private final String token; + private final Integer serializationHint; + + private final String sink; + private final String requestId; + + /** + * Construct the transport properties object. + * + * @param hash an HMAC generated on the data portion of the payload using the device key. + * @param priority uProtocol Prioritization classifications. + * @param ttl How long this event should live for after it was generated (in milliseconds). + * Events without this attribute (or value is 0) MUST NOT timeout. + * @param token Oauth2 access token to perform the access request defined in the request message. + * @param serializationHint hint regarding the bytes contained within the UPayload. + * @param sink an explicit destination URI. + * @param requestId The requestId is used to return a response for a specific request. + */ + private UAttributes(String hash, Priority priority, Integer ttl, + String token, Integer serializationHint, String sink, + String requestId) { + this.hash = hash; + this.priority = priority; + this.ttl = ttl; + this.token = token; + this.serializationHint = serializationHint; + this.sink = sink; + this.requestId = requestId; + } + + private UAttributes(UTransportAttributesBuilder builder) { + this(builder.hash, builder.priority, builder.ttl, builder.token, + builder.serializationHint, builder.sink, builder.requestId); + } + + /** + * Static factory method for creating an empty ultifi cloud event attributes object, to avoid working with null. + * @return Returns an empty transport attributes that indicates that there are no added additional attributes to configure. + */ + public static UAttributes empty() { + return EMPTY; + } + + public boolean isEmpty() { + return hash().isEmpty() && priority().isEmpty() && ttl().isEmpty() + && token().isEmpty() && serializationHint().isEmpty() + && requestId().isEmpty(); + } + + /** + * an HMAC generated on the data portion of the payload using the device key. + * @return Returns an Optional hash attribute. + */ + public Optional hash() { + return hash == null || hash.isBlank() ? Optional.empty() : Optional.of(hash); + } + + /** + * uProtocol Prioritization classifications. Default if not provided is LOW. + * @return Returns the configured uProtocol Prioritization classifications. + */ + public Optional priority() { + return priority == null ? Optional.empty() : Optional.of(priority); + } + + /** + * hint regarding the bytes contained within the UPayload. + * @return Returns an Optional hint regarding the bytes contained within the UPayload. + */ + public Optional ttl() { + return ttl == null ? Optional.empty() : Optional.of(this.ttl); + } + + /** + * Oauth2 access token to perform the access request defined in the request message. + * @return Returns an Optional token attribute. + */ + public Optional token() { + return token == null || token.isBlank() ? Optional.empty() : Optional.of(token); + } + + /** + * How long this event should live for after it was generated (in milliseconds). + * Events without this attribute (or value is 0) MUST NOT timeout. + * @return Returns an Optional time to live attribute. + */ + public Optional serializationHint() { + return serializationHint == null ? Optional.empty() : Optional.of(this.serializationHint); + } + + /** + * an explicit destination URI. + * @return Returns an Optional destination URI attribute. + */ + public Optional sink() { + return sink == null || sink.isBlank() ? Optional.empty() : Optional.of(sink); + } + + /** + * The requestId is used to return a response for a specific request. + * @return Returns an Optional requestId attribute. + */ + public Optional requestId() { + return requestId == null || requestId.isBlank() ? Optional.empty() : Optional.of(requestId); + } + + public static class UTransportAttributesBuilder { + private String hash; + private Priority priority; + private Integer ttl; + private String token; + private Integer serializationHint; + private String sink; + private String requestId; + + public UTransportAttributesBuilder() {} + + /** + * Add an HMAC generated on the data portion of the payload using the device key. + * @param hash an HMAC generated on the data portion of the CloudEvent message using the device key. + * @return Returns the UTransportAttributesBuilder with the configured hash. + */ + public UTransportAttributesBuilder withHash(String hash) { + this.hash = hash; + return this; + } + + /** + * Add uProtocol Prioritization classifications. + * @param priority the uProtocol Prioritization classifications. + * @return Returns the UTransportAttributesBuilder with the configured Priority. + */ + public UTransportAttributesBuilder withPriority(Priority priority) { + this.priority = priority; + return this; + } + + /** + * Add a time to live configuration. How long this event should live after it was generated. + * @param ttl How long this event should live for after it was generated (in milliseconds). + * Events without this attribute (or value is 0) MUST NOT timeout. + * @return Returns the UTransportAttributesBuilder with the configured time to live. + */ + public UTransportAttributesBuilder withTtl(Integer ttl) { + this.ttl = ttl; + return this; + } + + /** + * Add an Oauth2 access token to perform the access request defined in the request message. + * @param token an Oauth2 access token to perform the access request defined in the request message. + * @return Returns the UTransportAttributesBuilder with the configured token. + */ + public UTransportAttributesBuilder withToken(String token) { + this.token = token; + return this; + } + + /** + * Add a hint regarding the bytes contained within the UPayload. + * @param serializationHint hint regarding the bytes contained within the UPayload. + * @return Returns the UTransportAttributesBuilder with the configured serialization hint. + */ + public UTransportAttributesBuilder withSerializationHint(Integer serializationHint) { + this.serializationHint = serializationHint; + return this; + } + + /** + * Add an explicit destination URI. + * @param sink an explicit destination URI. + * @return Returns the UTransportAttributesBuilder with the configured destination URI. + */ + public UTransportAttributesBuilder withSink(String sink) { + this.sink = sink; + return this; + } + + /** + * The requestId is used to return a response for a specific request. + * @param requestId a requestId that is used to return a response for a specific request. + * @return Returns the UTransportAttributesBuilder with the configured requestId. + */ + public UTransportAttributesBuilder withRequestId(String requestId) { + this.requestId = requestId; + return this; + } + + /** + * Construct the UTransportAttributes from the builder. + * @return Returns a constructed UTransportAttributes. + */ + public UAttributes build() { + // validation if needed + return new UAttributes(this); + } + } + + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UAttributes that = (UAttributes) o; + return Objects.equals(hash, that.hash) && priority == that.priority && Objects.equals(ttl, that.ttl) + && Objects.equals(token, that.token) && Objects.equals(serializationHint, that.serializationHint) + && Objects.equals(sink, that.sink) && Objects.equals(requestId, that.requestId); + } + + @Override + public int hashCode() { + return Objects.hash(hash, priority, ttl, token, serializationHint, sink, requestId); + } + + @Override + public String toString() { + return "UTransportAttributes{" + + "hash='" + hash + '\'' + + ", priority=" + priority + + ", ttl=" + ttl + + ", token='" + token + '\'' + + ", serializationHint=" + serializationHint + + ", sink='" + sink + '\'' + + ", requestId='" + requestId + '\'' + + '}'; + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UListener.java b/src/main/java/org/eclipse/uprotocol/utransport/UListener.java new file mode 100644 index 00000000..d542404f --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/UListener.java @@ -0,0 +1,18 @@ +package org.eclipse.uprotocol.utransport; + + +/** + * For any implementation that defines some kind of callback or function that will be called to handle incoming messages. + */ +public interface UListener { + + /** + * Method called to handle/process events. + * @param topic Topic the underlying source of the message. + * @param payload Payload of the message. + * @param attributes Transportation attributes + * @return Returns an Ack every time a message is received and processed. + */ + Status onReceive(UTopic topic, UPayload payload, UAttributes attributes); + +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/UMessage.java new file mode 100644 index 00000000..956673c9 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/UMessage.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 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. + */ + + package org.eclipse.uprotocol.utransport; + + +/** + * The UMessage interface defines the uProtocol envelope for sending and receiving data. + */ +public interface UMessage { + + UTopic source(); + + UPayload payload(); + + UAttributes attributes(); +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UPayload.java b/src/main/java/org/eclipse/uprotocol/utransport/UPayload.java new file mode 100644 index 00000000..521b754d --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/UPayload.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 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. + */ + + package org.eclipse.uprotocol.utransport; + +import java.util.Arrays; + +/** + * The UPayload contains the clean Payload information at its raw serialized structure of a byte[] + */ +public class UPayload { + + private static final UPayload EMPTY = new UPayload(new byte[0]); + + private final byte[] data; + + + /** + * Create a UPayload. + * @param data A byte array of the actual data. + * @param representationHint Hint regarding what the bytes represent such as simple binary, a String or maybe a special type of String. + */ + public UPayload(byte[] data) { + this.data = data; + } + + /** + * The actual serialized or raw data, which can be deserialized or simply used as is using the hint. + * @return Returns the actual serialized or raw data, which can be deserialized or simply used as is using the hint. + */ + public byte[] data() { + return this.data; + } + + + /** + * @return Returns an empty representation of UPayload. + */ + public static UPayload empty() { + return EMPTY; + } + + /** + * @return Returns true if the data in the UPayload is empty. + */ + public boolean isEmpty() { + return this.data == null || this.data.length == 0; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UPayload uPayload = (UPayload) o; + return Arrays.equals(data, uPayload.data); + } + + @Override + public int hashCode() { + int result = Arrays.hashCode(data); + return result; + } + + @Override + public String toString() { + return "UPayload{" + + "data=" + Arrays.toString(data) + + '}'; + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTopic.java b/src/main/java/org/eclipse/uprotocol/utransport/UTopic.java new file mode 100644 index 00000000..189a558e --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/UTopic.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; + +/** + * Instead of changing the library at this moment, I am just creating a wrapper class. + */ +public class UTopic extends UUri { + + private static final UTopic EMPTY = new UTopic(UAuthority.empty(), UEntity.empty(), UResource.empty()); + + public UTopic(UAuthority uAuthority, UEntity uEntity, UResource uResource) { + super(uAuthority, uEntity, uResource); + } + + public static UTopic empty() { + return EMPTY; + } + + @Override + public String toString() { + return "UTopic{uAuthority=" + uAuthority() + ", uEntity=" + uEntity() + ", uResource=" + uResource() + "}"; + } + + public String toLog() { + return String.format("UTopic: %s/%s/%s/%s/%s/%s/%s", + uAuthority().device().orElse("local"), uAuthority().domain().orElse(""), + uEntity().name(), uEntity().version().orElse(""), + uResource().name(), uResource().instance().orElse(""), uResource().message().orElse("")); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java new file mode 100644 index 00000000..22f53a0d --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport; + +import org.eclipse.uprotocol.uri.datamodel.UEntity; + +/** + * 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. + */ +public interface UTransport { + + /** + * API to register the calling uE with the underlining transport implementation. + * @param uEntity uProtocol UEntity information + * @param token Deployment specific token used to authenticate the calling uE + * @return Returns Status if the registration is successful or not. + */ + Status register (UEntity uEntity, byte[] token) ; + + + /** + * Transmit UPayload to the topic using the attributes defined in UTransportAttributes. + * @param topic UTopic receiver of the payload. + * @param payload Actual payload. + * @param attributes Additional transport attributes. + * @return Returns an Status if managed to send to the underlying communication technology or not. + */ + Status send(UTopic topic, UPayload payload, UAttributes attributes); + + /** + * Register a method that will be called when a message comes in on the specific topic. + * @param topic UTopic of the message that arrived via the underlying transport technology. + * @param listener The method to execute to process the date for the topic. + * @return Returns an Ack if the method is registered successfully. + */ + Status registerListener(UTopic topic, UListener listener); + + /** + * Unregister a method on a topic. Messages arriving on this topic will no longer be processed by this listener. + * @param topic UTopic of the messages that will no longer be processed. + * @param listener The method to execute to process the date for the topic. + * @return Returns an Ack if the method is removed successfully. + */ + Status unregisterListener(UTopic topic, UListener listener); +} \ No newline at end of file From 2aa3f0394b328e84746040018a7aabe636d6eb48 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 24 Aug 2023 12:15:58 -0400 Subject: [PATCH 02/52] Interface & data model complete Still need to work on the test cases for 100% coverage then ensure documentation is up to date --- .../UMessage.java => rpc/RpcClient.java} | 26 +- .../uprotocol/uri/factory/UriFactory.java | 3 +- .../uprotocol/uri/validator/UriValidator.java | 69 ++++ .../utransport/CloudEventUMessage.java | 72 ----- .../utransport/CloudEventUMessageParser.java | 104 ------ .../uprotocol/utransport/EmptyUMessage.java | 76 ----- .../uprotocol/utransport/MessageType.java | 44 --- .../uprotocol/utransport/SimpleUMessage.java | 98 ------ .../eclipse/uprotocol/utransport/Status.java | 119 ------- .../uprotocol/utransport/UAttributes.java | 261 --------------- .../eclipse/uprotocol/utransport/UTopic.java | 55 ---- .../uprotocol/utransport/UTransport.java | 19 +- .../utransport/datamodel/UAttributes.java | 306 ++++++++++++++++++ .../utransport/{ => datamodel}/UListener.java | 5 +- .../utransport/datamodel/UMessageType.java | 69 ++++ .../utransport/{ => datamodel}/UPayload.java | 2 +- .../UPriority.java} | 14 +- .../USerializationHint.java} | 31 +- .../utransport/datamodel/UStatus.java | 225 +++++++++++++ .../validate/UAttributesValidator.java | 260 +++++++++++++++ .../uri/validator/UriValidatorTest.java | 137 ++++++++ .../validator/UAttributesValidatorTest.java | 73 +++++ 22 files changed, 1210 insertions(+), 858 deletions(-) rename src/main/java/org/eclipse/uprotocol/{utransport/UMessage.java => rpc/RpcClient.java} (51%) create mode 100644 src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/MessageType.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/Status.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UTopic.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java rename src/main/java/org/eclipse/uprotocol/utransport/{ => datamodel}/UListener.java (72%) create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java rename src/main/java/org/eclipse/uprotocol/utransport/{ => datamodel}/UPayload.java (97%) rename src/main/java/org/eclipse/uprotocol/utransport/{Priority.java => datamodel/UPriority.java} (82%) rename src/main/java/org/eclipse/uprotocol/utransport/{SerializationHint.java => datamodel/USerializationHint.java} (59%) create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java create mode 100644 src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UMessage.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java similarity index 51% rename from src/main/java/org/eclipse/uprotocol/utransport/UMessage.java rename to src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java index 956673c9..70db6bf5 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UMessage.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java @@ -19,17 +19,27 @@ * under the License. */ - package org.eclipse.uprotocol.utransport; +package org.eclipse.uprotocol.rpc; +import java.util.concurrent.CompletionStage; + +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes; +import org.eclipse.uprotocol.utransport.datamodel.UPayload; /** - * The UMessage interface defines the uProtocol envelope for sending and receiving data. + * The RpcClient interface defines the RPC client API per the uProtocol specification + * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l2/README.adoc + * */ -public interface UMessage { - - UTopic source(); - - UPayload payload(); +public interface RpcClient { - UAttributes attributes(); + /** + * Support for RPC method invocation. + * @param topic The topic to invoke the method on. + * @param payload The payload to send. + * @param attributes The attributes to send. + * @return Returns the CompletableFuture with the result or exception. + */ + CompletionStage invokeMethod(UUri topic, UPayload payload, UAttributes attributes); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index 1d0f3530..e9e92a47 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -101,7 +101,8 @@ static String buildUriForRpc(UAuthority uAuthority, sb.append("/"); } sb.append(buildSoftwareEntityPartOfUri(uEntitySource)); - sb.append("/rpc.response"); + sb.append("/"); + sb.append(UResource.response().nameWithInstance()); return sb.toString(); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java new file mode 100644 index 00000000..5267ded1 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -0,0 +1,69 @@ +package org.eclipse.uprotocol.uri.validator; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.utransport.datamodel.UStatus; +import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; + + +/** + * class for validating Uris. + */ +public abstract class UriValidator { + + /** + * Validate a Uri to ensure that it has at least a name for the uEntity. + * @param uri Uri to validate. + * @return Returns UStatus containing a success or a failure with the error message. + */ + public static UStatus validate(UUri uri) { + final UAuthority uAuthority = uri.uAuthority(); + if (uAuthority.isMarkedRemote()) { + if (uAuthority.device().isEmpty()) { + return UStatus.failed("Uri is configured to be remote and is missing uAuthority device name.", Code.INVALID_ARGUMENT); + } + } + if (uri.uEntity().name().isBlank()) { + return UStatus.failed("Uri is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); + } + return UStatus.ok(); + } + + /** + * Validate a Uri that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. + * @param uri Uri to validate. + * @return Returns the ValidationResult containing a success or a failure with the error message. + */ + public static UStatus validateRpcMethod(UUri uri) { + UStatus status = validate(uri); + if (status.isFailed()){ + return status; + } + final UResource uResource = uri.uResource(); + if (!uResource.isRPCMethod()) { + return UStatus.failed("Invalid RPC method uri. Uri should be the method to be called, or method from response.", Code.INVALID_ARGUMENT); + } + return UStatus.ok(); + } + + /** + * Validate a Uri that is meant to be used as an RPC response URI. Used in Request source values and Response sink values. + * + * @param uri Uri to validate. + * @return Returns the ValidationResult containing a success or a failure with the error message. + */ + public static UStatus validateRpcResponse(UUri uri) { + UStatus status = validate(uri); + if (status.isFailed()){ + return status; + } + + final UResource uResource = uri.uResource(); + if (!uResource.isRPCMethod() || !uResource.equals(UResource.response())) { + return UStatus.failed("Invalid RPC response type.", Code.INVALID_ARGUMENT); + } + + return UStatus.ok(); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java deleted file mode 100644 index 75dd48d5..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessage.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.eclipse.uprotocol.utransport; - - -import java.util.Objects; - -/** - * An implementation of a UMessage mapping from a CloudEvent. - */ -public class CloudEventUMessage extends SimpleUMessage implements UMessage { - - private final static Logger logger = LoggerFactory.getLogger(CloudEventUMessage.class); - - private final CloudEvent cloudEvent; - - private CloudEventUMessage(String id, UTopic source, UPayload payload, int priority, CloudEvent cloudEvent) { - super(id, source, payload, priority); - this.cloudEvent = cloudEvent; - } - - public static CloudEventUMessage fromCloudEvent(CloudEvent cloudEvent) { - logger.info("ce [{}]", cloudEvent); - CloudEvent ce; - if (cloudEvent == null) { - logger.info("ce is null"); - ce = CloudEventFactory.publish("ultifi:/", Any.getDefaultInstance(), UCloudEventAttributes.empty()); - } else { - ce = cloudEvent; - } - final UltifiUri ultifiUri = UltifiUriFactory.parseFromUri(UCloudEvent.getSource(ce)); - final Any cePayload = UCloudEvent.getPayload(ce); - final String cePriority = UCloudEvent.getPriority(ce) - .orElseGet(UCloudEventAttributes.Priority.LOW::qosString); - return new CloudEventUMessage(ce.getId(), - new UTopic(ultifiUri.uAuthority(), ultifiUri.uEntity(), ultifiUri.uResource()), - UPayload.fromProtoBytesofTypeAny(cePayload.toByteArray()), - calculatePriority(cePriority), - ce); - } - - public static int calculatePriority(String qosString) { - return Integer.parseInt(qosString.replace("CS", "")); - } - - public static CloudEventUMessage empty() { - return fromCloudEvent(null); - } - - public CloudEvent cloudEvent() { - return this.cloudEvent; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - CloudEventUMessage that = (CloudEventUMessage) o; - return Objects.equals(cloudEvent, that.cloudEvent); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), cloudEvent); - } - - @Override - public String toString() { - return "CloudEventUMessage{" + - "cloudEvent=" + cloudEvent + - "} " + super.toString(); - } -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java b/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java deleted file mode 100644 index 1a305d9e..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/CloudEventUMessageParser.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.eclipse.uprotocol.utransport; - -import java.net.URI; -import java.util.Optional; - -/** - * Parsing to and from the CloudEvent PDU - protocol data unit, a.k.a the requestRpcMessage envelope/object that contains the data & metadata. - * //TODO need to figure out attributes and other aspects of building the correct CloudEvent - * //TODO how to handle errors? I don't like exceptions very much. Sending something invalid over the wire is yucky as well. - */ -public record CloudEventUMessageParser() { - - private static final Logger logger = LoggerFactory.getLogger(CloudEventUMessageParser.class); - private static final String NONE = "NONE"; - - public static UMessage toUMessage(CloudEvent cloudEvent) { - logger.info("processing CloudEvent [{}]", cloudEvent); - if (cloudEvent == null) { - logger.info("CloudEvent is null"); - return SimpleUMessage.empty(); - } - final UltifiUri cloudEventsourceUri = UltifiUriFactory.parseFromUri(UCloudEvent.getSource(cloudEvent)); - final Any cePayload = UCloudEvent.getPayload(cloudEvent); - final String cloudEventType = cloudEvent.getType(); - final Optional maybeSink = UCloudEvent.getSink(cloudEvent); - if (UCloudEventType.REQUEST.type().equals(cloudEventType)) { - if (maybeSink.isPresent()) { - UltifiUri sink = UltifiUriFactory.parseFromUri(maybeSink.get()); - return RpcUMessage.buildRpcRequest(cloudEvent.getId(), - new UTopic(cloudEventsourceUri.uAuthority(), cloudEventsourceUri.uEntity(), cloudEventsourceUri.uResource()), - new UTopic(sink.uAuthority(), sink.uEntity(), sink.uResource()), - UPayload.fromProtoBytesofTypeAny(cePayload.toByteArray())); - } - } else if (UCloudEventType.RESPONSE.type().equals(cloudEventType)) { - if (maybeSink.isPresent()) { - UltifiUri sink = UltifiUriFactory.parseFromUri(maybeSink.get()); - return RpcUMessage.buildRpcResponse(cloudEvent.getId(), - new UTopic(sink.uAuthority(), sink.uEntity(), sink.uResource()), - new UTopic(cloudEventsourceUri.uAuthority(), cloudEventsourceUri.uEntity(), cloudEventsourceUri.uResource()), - UCloudEvent.getRequestId(cloudEvent).orElse(NONE), - UPayload.fromProtoBytesofTypeAny(cePayload.toByteArray())); - } - } - return CloudEventUMessage.fromCloudEvent(cloudEvent); - } - - public static CloudEvent toCloudEvent(UMessage uMessage) { - logger.info("building CloudEvent from [{}]", uMessage); - final UTopic sourceTopic = uMessage.source(); - String uMessageSource = UltifiUriFactory.buildUProtocolUri(sourceTopic.uAuthority(), - sourceTopic.uEntity(), sourceTopic.uResource()); - Any protoPayload = getProtoPayloadFromMessage(uMessage); - - if (uMessage instanceof RpcUMessage rpcUMessage) { - final boolean isRequest = rpcUMessage.isRPCRequest(); - final UTopic sinkTopic = rpcUMessage.sink(); - String serviceMethodForUri = UltifiUriFactory.buildUProtocolUri(sinkTopic.uAuthority(), - sinkTopic.uEntity(), sinkTopic.uResource()); - if (isRequest) { - return CloudEventFactory.buildBaseCloudEvent(rpcUMessage.id(), uMessageSource, - protoPayload.toByteArray(), protoPayload.getTypeUrl(), - UCloudEventAttributes.empty()) - .withType(UCloudEventType.REQUEST.type()) - .withExtension("sink", serviceMethodForUri) - .build(); - } else { - return CloudEventFactory.buildBaseCloudEvent(rpcUMessage.id(), serviceMethodForUri, - protoPayload.toByteArray(), protoPayload.getTypeUrl(), - UCloudEventAttributes.empty()) - .withType(UCloudEventType.RESPONSE.type()) - .withExtension("sink", URI.create(uMessageSource)) - .withExtension("reqid", rpcUMessage.requestId().orElse(NONE)) - .build(); - } - } - if (uMessage instanceof CloudEventUMessage cloudEventUMessage) { - logger.info("building CloudEventUMessage"); - return cloudEventUMessage.cloudEvent(); - } - if (uMessage instanceof SimpleUMessage) { - return CloudEventFactory.publish(uMessageSource, protoPayload, UCloudEventAttributes.empty()); - } - logger.error("building base cloud event since we don't know what we have"); - // we don't really know what we have, so build something - return CloudEventFactory.buildBaseCloudEvent( - CloudEventFactory.generateTimeOrderedCloudEventId(), - uMessageSource, - protoPayload.toByteArray(), - protoPayload.getTypeUrl(), - UCloudEventAttributes.empty()) - .build(); - } - - private static Any getProtoPayloadFromMessage(UMessage uMessage) { - try { - return Any.parseFrom(uMessage.payload().data()); - } catch (InvalidProtocolBufferException e) { - logger.error("Unable to build the CloudEvent payload since we can't parse the Payload into an Any object."); - return Any.getDefaultInstance(); - //throw new RuntimeException(e); - } - } - -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java deleted file mode 100644 index c1993fd7..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/EmptyUMessage.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.eclipse.uprotocol.utransport; - -import java.util.Objects; -import java.util.UUID; - -/** - * Class for returning new Empty Messages. This can be useful to return empty values in cases where there are - * errors. The requestRpcMessage still has a unique identifier for tracing but is empty since there is nothing to add since there was an error. - * TODO check if this is needed, or use a simple requestRpcMessage with empty - */ -public class EmptyUMessage implements UMessage { - - private final String id; - - /** - * Construct an EmptyUMessage. - * @param id Unique identifier of the requestRpcMessage. - */ - public EmptyUMessage(String id) { - this.id = id; - } - - public EmptyUMessage() { - this(UUID.randomUUID().toString()); - } - - @Override - public String id() { - return this.id; - } - - @Override - public UTopic source() { - return UTopic.empty(); - } - - @Override - public UPayload payload() { - return UPayload.empty(); - } - - @Override - public boolean isExpired() { - return false; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public String toLog() { - return toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - EmptyUMessage that = (EmptyUMessage) o; - return Objects.equals(id, that.id); - } - - @Override - public int hashCode() { - return Objects.hash(id); - } - - @Override - public String toString() { - return "EmptyUMessage{" + - "id='" + id + '\'' + - '}'; - } -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/MessageType.java b/src/main/java/org/eclipse/uprotocol/utransport/MessageType.java deleted file mode 100644 index 017fc9df..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/MessageType.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - - package org.eclipse.uprotocol.utransport; - -public enum MessageType { - PUBLISH(0, "pub.v1"), // Publish or notification event - REQUEST(1, "req.v1"), // Request - RESPONSE(2, "res.v1"); // Response - - private final int value; - private final String name; - - public int typeValue() { - return value; - } - - public String typeName() { - return name; - } - - MessageType(int value, String name) { - this.value = value; - this.name = name; - } -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java b/src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java deleted file mode 100644 index 47c723f7..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/SimpleUMessage.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.eclipse.uprotocol.uhello.akkaapp.sdk.umessage; - -import java.util.Objects; -import java.util.UUID; - -/** - * The most basic representation of a UMessage. - */ -public class SimpleUMessage implements UMessage { - - private static final SimpleUMessage EMPTY = new SimpleUMessage(null, UTopic.empty(), UPayload.empty(), 0); - - private final String Id; - private final UTopic source; - private final UPayload payload; - private final int priority; - - /** - * Create a simple UMessage. - * @param id Unique identifier of the requestRpcMessage. - * @param source The definition of the software where this requestRpcMessage originated, or the requester of an RPC. - * @param payload The actual raw bytes or serialized bytes containing the payload of the requestRpcMessage. - * @param priority some priority...? - */ - public SimpleUMessage(String id, UTopic source, UPayload payload, int priority) { - Id = Objects.requireNonNullElseGet(id, () -> UUID.randomUUID().toString()); - this.source = Objects.requireNonNullElseGet(source, UTopic::empty); - this.payload = Objects.requireNonNullElseGet(payload, UPayload::empty); - this.priority = priority; - } - - public SimpleUMessage(String id, UTopic source, UPayload payload) { - this(id, source, payload, 0); - } - - public SimpleUMessage(UTopic source, UPayload payload) { - this(null, source, payload, 0); - } - - public static SimpleUMessage empty() { - return EMPTY; - } - - @Override - public String id() { - return this.Id; - } - - @Override - public UTopic source() { - return this.source; - } - - @Override - public UPayload payload() { - return this.payload; - } - - @Override - public boolean isExpired() { - // since there is no ttl, this requestRpcMessage never expires. - return false; - } - - @Override - public boolean isEmpty() { - return this.source.isEmpty() && this.payload.isEmpty(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SimpleUMessage that = (SimpleUMessage) o; - return priority == that.priority && Objects.equals(Id, that.Id) - && Objects.equals(source, that.source) && Objects.equals(payload, that.payload); - } - - @Override - public int hashCode() { - return Objects.hash(Id, source, payload, priority); - } - - @Override - public String toString() { - return "SimpleUMessage{" + - "Id='" + Id + '\'' + - ", source=" + source + - ", payload=" + payload + - ", priority=" + priority + - '}'; - } - - public String toLog() { - return String.format("Id=%s, source=%s, priority=%s", - id(), source().toLog(), priority); - } -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/Status.java b/src/main/java/org/eclipse/uprotocol/utransport/Status.java deleted file mode 100644 index 26e74c96..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/Status.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.eclipse.uprotocol.utransport; - -import java.util.Objects; - -/** - * UProtocol general Ack requestRpcMessage for all operations. - * Can be made into a Monad in the future. - */ -public abstract class Status { - - private static final String OK = "ok"; - private static final String FAILED = "failed"; - - public abstract boolean isSuccess(); - public abstract String msg(); - - public boolean isFailed() { - return !isSuccess(); - } - - @Override - public String toString() { - return String.format("Ack %s %s %s", isSuccess() ? "ok" : "failed", - isSuccess() ? "id =" : "msg=", msg()); - } - - private static class OKSTATUS extends Status { - - /** - * A successful Ack can contain an id for tracking purposes. - */ - private final String id; - - private OKSTATUS(String id) { - this.id = id; - } - - @Override - public boolean isSuccess() { - return true; - } - - @Override - public String msg() { - return id; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - OKSTATUS okstatus = (OKSTATUS) o; - return Objects.equals(id, okstatus.id); - } - - @Override - public int hashCode() { - return Objects.hash(id); - } - - } - private static class FAILSTATUS extends Status { - - private final String failMsg; - - // TODO make this into an Enum so Steven does not loose his panties - private final int failureReason; - - private FAILSTATUS(String failMsg, int failureReason) { - this.failMsg = failMsg; - this.failureReason = failureReason; - } - - @Override - public boolean isSuccess() { - return false; - } - - @Override - public String msg() { - return this.failMsg; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - FAILSTATUS failstatus = (FAILSTATUS) o; - return failureReason == failstatus.failureReason && Objects.equals(failMsg, failstatus.failMsg); - } - - @Override - public int hashCode() { - return Objects.hash(failMsg, failureReason); - } - - } - - public static Status ok() { - return new OKSTATUS(Status.OK); - } - - public static Status ok(String ackId) { - return new OKSTATUS(ackId); - } - - public static Status failed() { - return new FAILSTATUS(FAILED, 0); - } - - public static Status failed(String msg) { - return new FAILSTATUS(msg, 0); - } - - public static Status failed(String msg, int failureReason) { - return new FAILSTATUS(msg, failureReason); - } - -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java deleted file mode 100644 index bf973bb6..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/UAttributes.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.utransport; - -import java.util.Objects; -import java.util.Optional; - -public class UAttributes { - - private static final UAttributes EMPTY = new UAttributes(null, null, null, null, null, null, null); - - private final String hash; - private final Priority priority; - private final Integer ttl; - private final String token; - private final Integer serializationHint; - - private final String sink; - private final String requestId; - - /** - * Construct the transport properties object. - * - * @param hash an HMAC generated on the data portion of the payload using the device key. - * @param priority uProtocol Prioritization classifications. - * @param ttl How long this event should live for after it was generated (in milliseconds). - * Events without this attribute (or value is 0) MUST NOT timeout. - * @param token Oauth2 access token to perform the access request defined in the request message. - * @param serializationHint hint regarding the bytes contained within the UPayload. - * @param sink an explicit destination URI. - * @param requestId The requestId is used to return a response for a specific request. - */ - private UAttributes(String hash, Priority priority, Integer ttl, - String token, Integer serializationHint, String sink, - String requestId) { - this.hash = hash; - this.priority = priority; - this.ttl = ttl; - this.token = token; - this.serializationHint = serializationHint; - this.sink = sink; - this.requestId = requestId; - } - - private UAttributes(UTransportAttributesBuilder builder) { - this(builder.hash, builder.priority, builder.ttl, builder.token, - builder.serializationHint, builder.sink, builder.requestId); - } - - /** - * Static factory method for creating an empty ultifi cloud event attributes object, to avoid working with null. - * @return Returns an empty transport attributes that indicates that there are no added additional attributes to configure. - */ - public static UAttributes empty() { - return EMPTY; - } - - public boolean isEmpty() { - return hash().isEmpty() && priority().isEmpty() && ttl().isEmpty() - && token().isEmpty() && serializationHint().isEmpty() - && requestId().isEmpty(); - } - - /** - * an HMAC generated on the data portion of the payload using the device key. - * @return Returns an Optional hash attribute. - */ - public Optional hash() { - return hash == null || hash.isBlank() ? Optional.empty() : Optional.of(hash); - } - - /** - * uProtocol Prioritization classifications. Default if not provided is LOW. - * @return Returns the configured uProtocol Prioritization classifications. - */ - public Optional priority() { - return priority == null ? Optional.empty() : Optional.of(priority); - } - - /** - * hint regarding the bytes contained within the UPayload. - * @return Returns an Optional hint regarding the bytes contained within the UPayload. - */ - public Optional ttl() { - return ttl == null ? Optional.empty() : Optional.of(this.ttl); - } - - /** - * Oauth2 access token to perform the access request defined in the request message. - * @return Returns an Optional token attribute. - */ - public Optional token() { - return token == null || token.isBlank() ? Optional.empty() : Optional.of(token); - } - - /** - * How long this event should live for after it was generated (in milliseconds). - * Events without this attribute (or value is 0) MUST NOT timeout. - * @return Returns an Optional time to live attribute. - */ - public Optional serializationHint() { - return serializationHint == null ? Optional.empty() : Optional.of(this.serializationHint); - } - - /** - * an explicit destination URI. - * @return Returns an Optional destination URI attribute. - */ - public Optional sink() { - return sink == null || sink.isBlank() ? Optional.empty() : Optional.of(sink); - } - - /** - * The requestId is used to return a response for a specific request. - * @return Returns an Optional requestId attribute. - */ - public Optional requestId() { - return requestId == null || requestId.isBlank() ? Optional.empty() : Optional.of(requestId); - } - - public static class UTransportAttributesBuilder { - private String hash; - private Priority priority; - private Integer ttl; - private String token; - private Integer serializationHint; - private String sink; - private String requestId; - - public UTransportAttributesBuilder() {} - - /** - * Add an HMAC generated on the data portion of the payload using the device key. - * @param hash an HMAC generated on the data portion of the CloudEvent message using the device key. - * @return Returns the UTransportAttributesBuilder with the configured hash. - */ - public UTransportAttributesBuilder withHash(String hash) { - this.hash = hash; - return this; - } - - /** - * Add uProtocol Prioritization classifications. - * @param priority the uProtocol Prioritization classifications. - * @return Returns the UTransportAttributesBuilder with the configured Priority. - */ - public UTransportAttributesBuilder withPriority(Priority priority) { - this.priority = priority; - return this; - } - - /** - * Add a time to live configuration. How long this event should live after it was generated. - * @param ttl How long this event should live for after it was generated (in milliseconds). - * Events without this attribute (or value is 0) MUST NOT timeout. - * @return Returns the UTransportAttributesBuilder with the configured time to live. - */ - public UTransportAttributesBuilder withTtl(Integer ttl) { - this.ttl = ttl; - return this; - } - - /** - * Add an Oauth2 access token to perform the access request defined in the request message. - * @param token an Oauth2 access token to perform the access request defined in the request message. - * @return Returns the UTransportAttributesBuilder with the configured token. - */ - public UTransportAttributesBuilder withToken(String token) { - this.token = token; - return this; - } - - /** - * Add a hint regarding the bytes contained within the UPayload. - * @param serializationHint hint regarding the bytes contained within the UPayload. - * @return Returns the UTransportAttributesBuilder with the configured serialization hint. - */ - public UTransportAttributesBuilder withSerializationHint(Integer serializationHint) { - this.serializationHint = serializationHint; - return this; - } - - /** - * Add an explicit destination URI. - * @param sink an explicit destination URI. - * @return Returns the UTransportAttributesBuilder with the configured destination URI. - */ - public UTransportAttributesBuilder withSink(String sink) { - this.sink = sink; - return this; - } - - /** - * The requestId is used to return a response for a specific request. - * @param requestId a requestId that is used to return a response for a specific request. - * @return Returns the UTransportAttributesBuilder with the configured requestId. - */ - public UTransportAttributesBuilder withRequestId(String requestId) { - this.requestId = requestId; - return this; - } - - /** - * Construct the UTransportAttributes from the builder. - * @return Returns a constructed UTransportAttributes. - */ - public UAttributes build() { - // validation if needed - return new UAttributes(this); - } - } - - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - UAttributes that = (UAttributes) o; - return Objects.equals(hash, that.hash) && priority == that.priority && Objects.equals(ttl, that.ttl) - && Objects.equals(token, that.token) && Objects.equals(serializationHint, that.serializationHint) - && Objects.equals(sink, that.sink) && Objects.equals(requestId, that.requestId); - } - - @Override - public int hashCode() { - return Objects.hash(hash, priority, ttl, token, serializationHint, sink, requestId); - } - - @Override - public String toString() { - return "UTransportAttributes{" + - "hash='" + hash + '\'' + - ", priority=" + priority + - ", ttl=" + ttl + - ", token='" + token + '\'' + - ", serializationHint=" + serializationHint + - ", sink='" + sink + '\'' + - ", requestId='" + requestId + '\'' + - '}'; - } -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTopic.java b/src/main/java/org/eclipse/uprotocol/utransport/UTopic.java deleted file mode 100644 index 189a558e..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/UTopic.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.utransport; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; - -/** - * Instead of changing the library at this moment, I am just creating a wrapper class. - */ -public class UTopic extends UUri { - - private static final UTopic EMPTY = new UTopic(UAuthority.empty(), UEntity.empty(), UResource.empty()); - - public UTopic(UAuthority uAuthority, UEntity uEntity, UResource uResource) { - super(uAuthority, uEntity, uResource); - } - - public static UTopic empty() { - return EMPTY; - } - - @Override - public String toString() { - return "UTopic{uAuthority=" + uAuthority() + ", uEntity=" + uEntity() + ", uResource=" + uResource() + "}"; - } - - public String toLog() { - return String.format("UTopic: %s/%s/%s/%s/%s/%s/%s", - uAuthority().device().orElse("local"), uAuthority().domain().orElse(""), - uEntity().name(), uEntity().version().orElse(""), - uResource().name(), uResource().instance().orElse(""), uResource().message().orElse("")); - } -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java index 22f53a0d..a4b55921 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java @@ -22,6 +22,11 @@ package org.eclipse.uprotocol.utransport; import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes; +import org.eclipse.uprotocol.utransport.datamodel.UListener; +import org.eclipse.uprotocol.utransport.datamodel.UPayload; +import org.eclipse.uprotocol.utransport.datamodel.UStatus; /** * UTransport is the uP-L1 interface that provides a common API for uE developers to send and receive messages. @@ -35,31 +40,31 @@ public interface UTransport { * @param token Deployment specific token used to authenticate the calling uE * @return Returns Status if the registration is successful or not. */ - Status register (UEntity uEntity, byte[] token) ; + UStatus register (UEntity uEntity, byte[] token) ; /** * Transmit UPayload to the topic using the attributes defined in UTransportAttributes. - * @param topic UTopic receiver of the payload. + * @param topic UUri receiver of the payload. * @param payload Actual payload. * @param attributes Additional transport attributes. * @return Returns an Status if managed to send to the underlying communication technology or not. */ - Status send(UTopic topic, UPayload payload, UAttributes attributes); + UStatus send(UUri topic, UPayload payload, UAttributes attributes); /** * Register a method that will be called when a message comes in on the specific topic. - * @param topic UTopic of the message that arrived via the underlying transport technology. + * @param topic UUri of the message that arrived via the underlying transport technology. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is registered successfully. */ - Status registerListener(UTopic topic, UListener listener); + UStatus registerListener(UUri topic, UListener listener); /** * Unregister a method on a topic. Messages arriving on this topic will no longer be processed by this listener. - * @param topic UTopic of the messages that will no longer be processed. + * @param topic UUri of the messages that will no longer be processed. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is removed successfully. */ - Status unregisterListener(UTopic topic, UListener listener); + UStatus unregisterListener(UUri topic, UListener listener); } \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java new file mode 100644 index 00000000..5a3cf87f --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport.datamodel; + +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.uprotocol.uri.datamodel.UUri; + +public class UAttributes { + + private static final UAttributes EMPTY = new UAttributes(null, null, null, null, null, null, null, null, null, null); + + // Required Attributes + private final UUID id; // Unique identifier for the message + private final UMessageType type; // Message type + private final UPriority priority; // Message priority + + // Optional Attributes + private final Integer ttl; // Time to live in milliseconds + private final String token; // Authorization token used for TAP + private final USerializationHint hint; // Hint regarding the bytes contained within the UPayload + private final UUri sink; // Explicit destination URI + private final Integer plevel; // Permission Level + private final Integer commstatus; // Communication Status + private final UUID reqid; // Request ID + + + /** + * Construct the transport UAttributes object. + * + * @param id Unique identifier for the message + * @param type Message type + * @param priority Message priority + * @param ttl Time to live in milliseconds + * @param token Authorization token used for TAP + * @param hint Hint regarding the bytes contained within the UPayload + * @param sink Explicit destination URI + * @param plevel Permission Level + * @param commstatus Communication Status + * @param reqid Request ID + * @return Returns a constructed UAttributes. + */ + private UAttributes(UUID id, UMessageType type, UPriority priority, Integer ttl, String token, + USerializationHint hint, UUri sink, Integer plevel, Integer commstatus, UUID reqid) { + this.id = id; + this.type = type; + this.priority = priority; + this.ttl = ttl; + this.token = token; + this.hint = hint; + this.sink = sink; + this.plevel = plevel; + this.commstatus = commstatus; + this.reqid = reqid; + } + + private UAttributes(UAttributesBuilder builder) { + this(builder.id, builder.type, builder.priority, builder.ttl, builder.token, builder.hint, builder.sink, + builder.plevel, builder.commstatus, builder.reqid); + } + + + /** + * Static factory method for creating an empty ultifi cloud event attributes object, to avoid working with null. + * @return Returns an empty transport attributes that indicates that there are no added additional attributes to configure. + */ + public static UAttributes empty() { + return EMPTY; + } + + public boolean isEmpty() { + return this.id == null && this.type == null && this.priority == null && this.ttl == null && this.token == null + && this.hint == null && this.sink == null && this.plevel == null && this.commstatus == null + && this.reqid == null; + } + + /** + * Unique identifier for the message. + * @return Returns the unique identifier for the message. + */ + public UUID id() { + return id; + } + + /** + * Message type. + * @return Returns the message type. + */ + public UMessageType type() { + return type; + } + + /** + * uProtocol Prioritization classifications. + * @return Returns the configured uProtocol Prioritization classifications. + */ + public UPriority priority() { + return priority; + } + + /** + * hint regarding the bytes contained within the UPayload. + * @return Returns an Optional hint regarding the bytes contained within the UPayload. + */ + public Optional ttl() { + return ttl == null ? Optional.empty() : Optional.of(this.ttl); + } + + /** + * Oauth2 access token to perform the access request defined in the request message. + * @return Returns an Optional token attribute. + */ + public Optional token() { + return token == null || token.isBlank() ? Optional.empty() : Optional.of(token); + } + + /** + * How long this event should live for after it was generated (in milliseconds). + * Events without this attribute (or value is 0) MUST NOT timeout. + * @return Returns an Optional time to live attribute. + */ + public Optional serializationHint() { + return hint == null ? Optional.empty() : Optional.of(this.hint); + } + + /** + * an explicit destination URI. + * @return Returns an Optional destination URI attribute. + */ + public Optional sink() { + return sink == null || sink.isEmpty() ? Optional.empty() : Optional.of(sink); + } + + /** + * The reqid is used to return a response for a specific request. + * @return Returns an Optional requestId attribute. + */ + public Optional reqid() { + return reqid == null ? Optional.empty() : Optional.of(reqid); + } + + /** + * The permission level of the message. + * @return Returns an Optional permission level attribute. + */ + public Optional plevel() { + return plevel == null ? Optional.empty() : Optional.of(plevel); + } + + /** + * The communication status of the message. + * @return Returns an Optional communication status attribute. + */ + public Optional commstatus() { + return commstatus == null ? Optional.empty() : Optional.of(commstatus); + } + + + /** + * Builder for the UAttributes object. + */ + public static class UAttributesBuilder { + + private UUID id; + private UMessageType type; + private UPriority priority; + private Integer ttl; + private String token; + private USerializationHint hint; + private UUri sink; + private Integer plevel; + private Integer commstatus; + private UUID reqid; + + public UAttributesBuilder() {} + + /** + * Add uProtocol Prioritization classifications. + * @param priority the uProtocol Prioritization classifications. + * @return Returns the UAttributesBuilder with the configured Priority. + */ + public UAttributesBuilder withPriority(UPriority priority) { + this.priority = priority; + return this; + } + + /** + * Add the unique identifier for the message. + * @param id the unique identifier for the message. + * @return Returns the UAttributesBuilder with the configured id. + */ + public UAttributesBuilder withId(UUID id) { + this.id = id; + return this; + } + + /** + * Add the message type. + * @param type the message type. + * @return Returns the UAttributesBuilder with the configured type. + */ + public UAttributesBuilder withType(UMessageType type) { + this.type = type; + return this; + } + + /** + * Add the time to live in milliseconds. + * @param ttl the time to live in milliseconds. + * @return Returns the UAttributesBuilder with the configured ttl. + */ + public UAttributesBuilder withTtl(Integer ttl) { + this.ttl = ttl; + return this; + } + + /** + * Add the authorization token used for TAP. + * @param token the authorization token used for TAP. + * @return Returns the UAttributesBuilder with the configured token. + */ + public UAttributesBuilder withToken(String token) { + this.token = token; + return this; + } + + /** + * Add the hint regarding the bytes contained within the UPayload. + * @param hint the hint regarding the bytes contained within the UPayload. + * @return Returns the UAttributesBuilder with the configured hint. + */ + public UAttributesBuilder withHint(USerializationHint hint) { + this.hint = hint; + return this; + } + + /** + * Add the explicit destination URI. + * @param sink the explicit destination URI. + * @return Returns the UAttributesBuilder with the configured sink. + */ + public UAttributesBuilder withSink(UUri sink) { + this.sink = sink; + return this; + } + + /** + * Add the permission level of the message. + * @param plevel the permission level of the message. + * @return Returns the UAttributesBuilder with the configured plevel. + */ + public UAttributesBuilder withPlevel(Integer plevel) { + this.plevel = plevel; + return this; + } + + /** + * Add the communication status of the message. + * @param commstatus the communication status of the message. + * @return Returns the UAttributesBuilder with the configured commstatus. + */ + public UAttributesBuilder withCommstatus(Integer commstatus) { + this.commstatus = commstatus; + return this; + } + + /** + * Add the request ID. + * @param reqid the request ID. + * @return Returns the UAttributesBuilder with the configured reqid. + */ + public UAttributesBuilder withReqid(UUID reqid) { + this.reqid = reqid; + return this; + } + + /** + * Construct the UAttributes from the builder. + * @return Returns a constructed UAttributes. + */ + public UAttributes build() { + // validation if needed + return new UAttributes(this); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UListener.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UListener.java similarity index 72% rename from src/main/java/org/eclipse/uprotocol/utransport/UListener.java rename to src/main/java/org/eclipse/uprotocol/utransport/datamodel/UListener.java index d542404f..32e392e1 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UListener.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UListener.java @@ -1,5 +1,6 @@ -package org.eclipse.uprotocol.utransport; +package org.eclipse.uprotocol.utransport.datamodel; +import org.eclipse.uprotocol.uri.datamodel.UUri; /** * For any implementation that defines some kind of callback or function that will be called to handle incoming messages. @@ -13,6 +14,6 @@ public interface UListener { * @param attributes Transportation attributes * @return Returns an Ack every time a message is received and processed. */ - Status onReceive(UTopic topic, UPayload payload, UAttributes attributes); + UStatus onReceive(UUri topic, UPayload payload, UAttributes attributes); } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java new file mode 100644 index 00000000..ae47ffaa --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 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. + */ + + package org.eclipse.uprotocol.utransport.datamodel; + +import java.util.Arrays; +import java.util.Optional; + +public enum UMessageType { + PUBLISH(0, "pub.v1"), // Publish or notification event + REQUEST(1, "req.v1"), // Request + RESPONSE(2, "res.v1"); // Response + + private final int intValue; + private final String stringValue; + + public int intValue() { + return intValue; + } + + public String stringValue() { + return stringValue; + } + + UMessageType(int value, String name) { + this.intValue = value; + this.stringValue = name; + } + + /** + * Find the Message type from a numeric value. Mind you, it might not exist. + * @param value numeric message type . + * @return Returns the UMessageType matching the numeric value + */ + public static Optional from(int value) { + return Arrays.stream(UMessageType.values()) + .filter(p -> p.intValue() == value) + .findAny(); + } + + /** + * Find the Message type from a string value. Mind you, it might not exist. + * @param value string message type . + * @return Returns the UMessageType matching the string value + */ + public static Optional from(String value) { + return Arrays.stream(UMessageType.values()) + .filter(p -> p.stringValue().equals(value)) + .findAny(); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UPayload.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java similarity index 97% rename from src/main/java/org/eclipse/uprotocol/utransport/UPayload.java rename to src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java index 521b754d..1726ea1c 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java @@ -19,7 +19,7 @@ * under the License. */ - package org.eclipse.uprotocol.utransport; + package org.eclipse.uprotocol.utransport.datamodel; import java.util.Arrays; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/Priority.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPriority.java similarity index 82% rename from src/main/java/org/eclipse/uprotocol/utransport/Priority.java rename to src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPriority.java index 66d7b483..747e4708 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/Priority.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPriority.java @@ -1,9 +1,9 @@ -package org.eclipse.uprotocol.utransport; +package org.eclipse.uprotocol.utransport.datamodel; import java.util.Arrays; import java.util.Optional; -public enum Priority { +public enum UPriority { // Low Priority. No bandwidth assurance such as File Transfer. LOW ("CS0", 0), // Standard, undifferentiated application such as General (unclassified). @@ -29,7 +29,7 @@ public int intValue() { return value; } - Priority(String qosString, int value) { + UPriority(String qosString, int value) { this.qosString = qosString; this.value = value; } @@ -39,8 +39,8 @@ public int intValue() { * @param value numeric priority value. * @return Returns the Priority matching the numeric value. Mind you, it might not exist. */ - public static Optional from(int value) { - return Arrays.stream(Priority.values()) + public static Optional from(int value) { + return Arrays.stream(UPriority.values()) .filter(p -> p.intValue() == value) .findAny(); } @@ -50,8 +50,8 @@ public static Optional from(int value) { * @param qosString QOS String priority value. * @return Returns the Priority matching the QOS String value. Mind you, it might not exist. */ - public static Optional from(String qosString) { - return Arrays.stream(Priority.values()) + public static Optional from(String qosString) { + return Arrays.stream(UPriority.values()) .filter(p -> p.qosString().equals(qosString)) .findAny(); } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java similarity index 59% rename from src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java rename to src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java index e0d03136..f15efd13 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/SerializationHint.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java @@ -19,9 +19,12 @@ * under the License. */ -package org.eclipse.uprotocol.utransport; +package org.eclipse.uprotocol.utransport.datamodel; -public enum SerializationHint { +import java.util.Arrays; +import java.util.Optional; + +public enum USerializationHint { UNKNOWN(0, ""), PROTOBUF (1, "application/x-protobuf"), // data is a Base64 encoded protobuf string JSON(2, "application/json"), // data is a UTF-8 string containing a JSON structure @@ -39,9 +42,31 @@ public String mimeType() { return mimeType; } - SerializationHint(int hintNumber, String mimeType) { + USerializationHint(int hintNumber, String mimeType) { this.hintNumber = hintNumber; this.mimeType = mimeType; } + + /** + * Find the serialization hint matching the mimeType value. Mind you, it might not exist. + * @param value numeric hint value. + * @return Returns the USerializationHint matching the numeric value. + */ + public static Optional from(int value) { + return Arrays.stream(USerializationHint.values()) + .filter(p -> p.hintNumber() == value) + .findAny(); + } + + /** + * Find the serialization hint matching the String value. Mind you, it might not exist. + * @param value String hint value. + * @return Returns the USerializationHint matching the String value. + */ + public static Optional from(String value) { + return Arrays.stream(USerializationHint.values()) + .filter(p -> p.mimeType().equals(value)) + .findAny(); + } } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java new file mode 100644 index 00000000..75388bcb --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java @@ -0,0 +1,225 @@ +package org.eclipse.uprotocol.utransport.datamodel; + +import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; + + +/** + * UProtocol general Ack requestRpcMessage for all operations. + * Can be made into a Monad in the future. + */ +public abstract class UStatus { + + private static final String OK = "ok"; + private static final String FAILED = "failed"; + + public abstract boolean isSuccess(); + public abstract String msg(); + + public abstract int getCode(); + + /** + * Enum to contain the status code that we map to google.rpc.Code + * + * Please refer to https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto + * for documentation on the codes listed below + * + */ + public enum Code { + + OK(com.google.rpc.Code.OK_VALUE), + CANCELLED(com.google.rpc.Code.CANCELLED_VALUE), + UNKNOWN(com.google.rpc.Code.UNKNOWN_VALUE), + INVALID_ARGUMENT(com.google.rpc.Code.INVALID_ARGUMENT_VALUE), + DEADLINE_EXCEEDED(com.google.rpc.Code.DEADLINE_EXCEEDED_VALUE), + NOT_FOUND(com.google.rpc.Code.NOT_FOUND_VALUE), + ALREADY_EXISTS(com.google.rpc.Code.ALREADY_EXISTS_VALUE), + PERMISSION_DENIED(com.google.rpc.Code.PERMISSION_DENIED_VALUE), + UNAUTHENTICATED(com.google.rpc.Code.UNAUTHENTICATED_VALUE), + RESOURCE_EXHAUSTED(com.google.rpc.Code.RESOURCE_EXHAUSTED_VALUE), + FAILED_PRECONDITION(com.google.rpc.Code.FAILED_PRECONDITION_VALUE), + ABORTED(com.google.rpc.Code.ABORTED_VALUE), + OUT_OF_RANGE(com.google.rpc.Code.OUT_OF_RANGE_VALUE), + UNIMPLEMENTED(com.google.rpc.Code.UNIMPLEMENTED_VALUE), + INTERNAL(com.google.rpc.Code.INTERNAL_VALUE), + UNAVAILABLE(com.google.rpc.Code.UNAVAILABLE_VALUE), + DATA_LOSS(com.google.rpc.Code.DATA_LOSS_VALUE), + UNSPECIFIED(-1); + + private int value; + private Code(int value) { + this.value = value; + } + + public int value() { + return value; + } + + /** + * Get the Code from an integer value + * @param value The integer value of the Code + * @return Returns the Code if found, otherwise returns Optional.empty() + */ + public static Optional from(int value) { + return Arrays.stream(Code.values()) + .filter(p -> p.value() == value) + .findAny(); + } + + + /** + * Get the Code from a google.rpc.Code + * @param code The google.rpc.Code + * @return Returns the Code if found, otherwise returns Optional.empty() + */ + public static Optional from(com.google.rpc.Code code) { + if ( (code == null) || (code == com.google.rpc.Code.UNRECOGNIZED) ) { + return Optional.empty(); + } + return Arrays.stream(Code.values()) + .filter(p -> p.value() == code.getNumber()) + .findAny(); + } + } + + + /** + * Return true if UStatus is a failure + * @return Returns true if the UStatus is successful. + */ + public boolean isFailed() { + return !isSuccess(); + } + + + @Override + public String toString() { + return String.format("UMessage %s %s %s", isSuccess() ? "ok" : "failed", + isSuccess() ? "id =" : "msg=", msg()); + } + + /** + * A successful UStatus + */ + private static class OKSTATUS extends UStatus { + + /** + * A successful status could contain an id for tracking purposes. + */ + private final String id; + + private OKSTATUS(String id) { + this.id = id; + } + + @Override + public boolean isSuccess() { + return true; + } + + public int getCode() { + return Code.OK.value(); + } + + @Override + public String msg() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OKSTATUS okstatus = (OKSTATUS) o; + return Objects.equals(id, okstatus.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + } + + + /** + * A failed UStatus + */ + private static class FAILSTATUS extends UStatus { + + private final String failMsg; + + private final Code code; + + private FAILSTATUS(String failMsg, Code code) { + this.failMsg = failMsg; + this.code = code; + } + + private FAILSTATUS(String failMsg, int value) { + Optional code = Code.from(value); + this.failMsg = failMsg; + if (code.isPresent()) { + this.code = code.get(); + } else { + this.code = Code.UNSPECIFIED; + } + } + + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public String msg() { + return this.failMsg; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FAILSTATUS failstatus = (FAILSTATUS) o; + return code == failstatus.code && Objects.equals(failMsg, failstatus.failMsg); + } + + @Override + public int hashCode() { + return Objects.hash(failMsg, code); + } + + @Override + public int getCode() { + return code.value; + } + } + + + public static UStatus ok() { + return new OKSTATUS(UStatus.OK); + } + + public static UStatus ok(String ackId) { + return new OKSTATUS(ackId); + } + + public static UStatus failed() { + return new FAILSTATUS(FAILED, 0); + } + + public static UStatus failed(String msg) { + return new FAILSTATUS(msg, 0); + } + + public static UStatus failed(String msg, int failureReason) { + return new FAILSTATUS(msg, failureReason); + } + + public static UStatus failed(String msg, Code code) { + return new FAILSTATUS(msg, code); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java new file mode 100644 index 00000000..34926e33 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java @@ -0,0 +1,260 @@ +package org.eclipse.uprotocol.utransport.validate; + +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.validator.UriValidator; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes; +import org.eclipse.uprotocol.utransport.datamodel.UMessageType; +import org.eclipse.uprotocol.utransport.datamodel.UStatus; +import org.eclipse.uprotocol.uuid.factory.UUIDUtils; + +import com.google.rpc.Code; + +/** + * Abstract class for validating UAttributes. + * + * UPriority is not validated since it cannot be anything other than a valid UPriority. + * + * + */ +public abstract class UAttributesValidator { + + public static UAttributesValidator getValidator(UAttributes attribute) { + if (attribute.type() == null) { + return Validators.PUBLISH.validator(); + } + switch (attribute.type()){ + case RESPONSE: + return Validators.RESPONSE.validator(); + case REQUEST: + return Validators.REQUEST.validator(); + default: + return Validators.PUBLISH.validator(); + } + } + + + + /** + * Enum that hold the implementations of uattributesValidator according to type. + */ + public enum Validators { + PUBLISH (new Publish()), + REQUEST (new Request()), + RESPONSE (new Response()); + + private final UAttributesValidator uattributesValidator; + + public UAttributesValidator validator() { + return uattributesValidator; + } + + Validators(UAttributesValidator uattributesValidator) { + this.uattributesValidator = uattributesValidator; + } + } + + + public UStatus validate(UAttributes attributes) { + final String errorMessage = Stream.of(validateType(attributes), + validateId(attributes), + validateSink(attributes), + validatePriority(attributes), + validateCommStatus(attributes), + validateTtl(attributes), + validatePermissionLevel(attributes), + validateCorrelationId(attributes)) + .filter(UStatus::isFailed) + .map(UStatus::msg) + .collect(Collectors.joining(",")); + return errorMessage.isBlank() ? UStatus.ok() : + UStatus.failed("Invalid argument", Code.INVALID_ARGUMENT_VALUE); + } + + + public UStatus validatePriority(UAttributes attributes) { + return attributes.priority() != null ? UStatus.ok() : UStatus.failed(); + } + + public UStatus validateTtl(UAttributes attributes) { + Optional ttl = attributes.ttl(); + if (ttl.isPresent()) { + return ttl.get() > 0 ? UStatus.ok() : UStatus.failed(); + } + return UStatus.ok(); + } + + public UStatus validateId(UAttributes attributes) { + try { + return UUIDUtils.isUuid(attributes.id()) ? UStatus.ok() : UStatus.failed(); + } catch (Exception e) { + return UStatus.failed(); + } + } + + /** + * Validate the sink Uri for the default case. + * @param attributes UAttributes to validate + * @return Returns a UStatus indicating if the Uri is valid or not. + */ + public UStatus validateSink(UAttributes attributes) { + if (!attributes.sink().isEmpty()){ + return UriValidator.validate(attributes.sink().get()); + } + return UStatus.ok(); + } + + /** + * Validate the commStatus for the default case. + * @param attributes UAttributes to validate + * @return Returns a UStatus indicating if the commStatus is valid or not. + */ + public UStatus validateCommStatus(UAttributes attributes) { + if (!attributes.commstatus().isEmpty()){ + return Code.forNumber(attributes.commstatus().get()) != null ? UStatus.ok() : UStatus.failed(); + } + return UStatus.ok(); + } + + /** + * Validate the permissionLevel for the default case. + * @param attributes UAttributes to validate + * @return Returns a UStatus indicating if the permissionLevel is valid or not. + */ + public UStatus validatePermissionLevel(UAttributes attributes) { + final Optional plevel = attributes.plevel(); + if (plevel.isPresent()) { + + return plevel.get() > 0 ? UStatus.ok() : UStatus.failed(); + } + return UStatus.ok(); + } + + /** + * Validate the correlationId for the default case. + * @param attributes UAttributes to validate + * @return Returns a UStatus indicating if the correlationId is valid or not. + */ + public UStatus validateCorrelationId(UAttributes attributes) { + final Optional correlationId = attributes.reqid(); + + if (correlationId.isPresent()) { + return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : UStatus.failed(); + } + return UStatus.ok(); + } + + + /** + * Validate the MessageType of UAttributes + * @param attributes UAttributes to validate + * @return Returns a UStatus indicating if the MessageType is valid or not. + */ + public abstract UStatus validateType(UAttributes attributes); + + + /** + * PUBLISH UAttributes Validator + * + */ + private static class Publish extends UAttributesValidator { + + /** + * Validate UAttributes with type UMessageType PUBLISH + * @param attributes UAttributes to validate + * @return Returns a UStatus indicating if the MessageType is valid or not. + */ + @Override + public UStatus validateType(UAttributes attributes) { + return attributes.type() == UMessageType.PUBLISH ? UStatus.ok() : UStatus.failed(); + } + } + + /** + * Validate UAttributes with type UMessageType Request + */ + private static class Request extends UAttributesValidator { + + @Override + public UStatus validateType(UAttributes attributes) { + return attributes.type() == UMessageType.REQUEST ? UStatus.ok() : UStatus.failed(); + } + + /** + * Validate the sink Uri. + * @param attributes + * @return Returns a UStatus indicating if the Uri is valid or not. + */ + @Override + public UStatus validateSink(UAttributes attributes) { + final Optional sink = attributes.sink(); + + if (!sink.isPresent()) { + return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT_VALUE); + } + return UriValidator.validateRpcResponse(sink.get()); + } + + /** + * Validate the ttl. + * @param attributes + * @return Returns a UStatus indicating if the ttl is valid or not. + */ + @Override + public UStatus validateTtl(UAttributes attributes) { + final Optional ttl = attributes.ttl(); + if (!ttl.isPresent()) { + return UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT_VALUE); + } else { + return ttl.get() > 0 ? UStatus.ok() : UStatus.failed(); + } + } + } + + + /** + * Validate UAttributes with type UMessageType RESPONSE + */ + private static class Response extends UAttributesValidator { + + @Override + public UStatus validateType(UAttributes attributes) { + return attributes.type() == UMessageType.RESPONSE ? UStatus.ok() : UStatus.failed(); + } + + /** + * Validate the sink Uri. + * @param attributes + * @return Returns a UStatus indicating if the Uri is valid or not. + */ + @Override + public UStatus validateSink(UAttributes attributes) { + final Optional sink = attributes.sink(); + + if (!sink.isPresent()) { + return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT_VALUE); + } + return UriValidator.validateRpcMethod(sink.get()); + } + + /** + * Validate the correlationId for the default case. + * @param attributes + * @return Returns a UStatus indicating if the correlationId is valid or not. + */ + @Override + public UStatus validateCorrelationId(UAttributes attributes) { + final Optional correlationId = attributes.reqid(); + + if (!correlationId.isPresent()) { + return UStatus.failed("Missing correlationId", Code.INVALID_ARGUMENT_VALUE); + } + return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : UStatus.failed(); + } + } + +} diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java new file mode 100644 index 00000000..c9d5134c --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.validator; + + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.utransport.datamodel.UStatus; +import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; + +class UriValidatorTest { + + @Test + @DisplayName("Test validate blank uri") + public void test_validate_blank_uri() { + final UUri uri = UriFactory.parseFromUri(null); + final UStatus status = UriValidator.validate(uri); + assertTrue(uri.isEmpty()); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + } + + @Test + @DisplayName("Test validate uri with no device name") + public void test_validate_uri_with_no_entity_name() { + final UUri uri = UriFactory.parseFromUri("//"); + final UStatus status = UriValidator.validate(uri); + assertTrue(uri.isEmpty()); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Uri is configured to be remote and is missing uAuthority device name.", status.msg()); + } + + @Test + @DisplayName("Test validate uri with uEntity") + public void test_validate_uri_with_uEntity() { + final UUri uri = UriFactory.parseFromUri("/hartley"); + final UStatus status = UriValidator.validate(uri); + assertEquals(UStatus.ok(), status); + } + + @Test + @DisplayName("Test validate with malformed URI") + public void test_validate_with_malformed_uri() { + final UUri uri = UriFactory.parseFromUri("hartley"); + final UStatus status = UriValidator.validate(uri); + assertTrue(uri.isEmpty()); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + } + + @Test + @DisplayName("Test validateRpcMethod with valid URI") + public void test_validateRpcMethod_with_valid_uri() { + final UUri uri = UriFactory.parseFromUri("/hartley//rpc.echo"); + final UStatus status = UriValidator.validateRpcMethod(uri); + assertEquals(UStatus.ok(), status); + } + + @Test + @DisplayName("Test validateRpcMethod with valid URI") + public void test_validateRpcMethod_with_invalid_uri() { + final UUri uri = UriFactory.parseFromUri("/hartley/echo"); + final UStatus status = UriValidator.validateRpcMethod(uri); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.msg()); + } + + @Test + @DisplayName("Test validateRpcMethod with malformed URI") + public void test_validateRpcMethod_with_malformed_uri() { + final UUri uri = UriFactory.parseFromUri("hartley"); + final UStatus status = UriValidator.validateRpcMethod(uri); + assertTrue(uri.isEmpty()); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + } + + @Test + @DisplayName("Test validateRpcResponse with valid URI") + public void test_validateRpcResponse_with_valid_uri() { + final UUri uri = UriFactory.parseFromUri("/hartley//rpc.response"); + final UStatus status = UriValidator.validateRpcResponse(uri); + assertEquals(UStatus.ok(), status); + } + + @Test + @DisplayName("Test validateRpcResponse with malformed URI") + public void test_validateRpcResponse_with_malformed_uri() { + final UUri uri = UriFactory.parseFromUri("hartley"); + final UStatus status = UriValidator.validateRpcResponse(uri); + assertTrue(uri.isEmpty()); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + } + + @Test + @DisplayName("Test validateRpcResponse with rpc type") + public void test_validateRpcResponse_with_rpc_type() { + final UUri uri = UriFactory.parseFromUri("/hartley//dummy.wrong"); + final UStatus status = UriValidator.validateRpcResponse(uri); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Invalid RPC response type.", status.msg()); + } + + @Test + @DisplayName("Test validateRpcResponse with invalid rpc response type") + public void test_validateRpcResponse_with_invalid_rpc_response_type() { + final UUri uri = UriFactory.parseFromUri("/hartley//rpc.wrong"); + final UStatus status = UriValidator.validateRpcResponse(uri); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Invalid RPC response type.", status.msg()); + } +} diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java new file mode 100644 index 00000000..09e19627 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport.validator; + + +import static org.junit.Assert.assertNull; + +import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes; +import org.eclipse.uprotocol.utransport.datamodel.UMessageType; +import org.eclipse.uprotocol.utransport.datamodel.UPriority; +import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; +import org.eclipse.uprotocol.utransport.validate.UAttributesValidator; +import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + + +class UAttributesValidatorTest { + + @Test + @DisplayName("test fetching validator for valid types") + public void test_fetching_validator_for_valid_types() { + + UAttributesValidator publish = UAttributesValidator.getValidator(new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .withType(UMessageType.PUBLISH) + .build()); + assert(publish instanceof UAttributesValidator); + + UAttributesValidator request = UAttributesValidator.getValidator(new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .withType(UMessageType.REQUEST) + .build()); + assert(request instanceof UAttributesValidator); + + UAttributesValidator response = UAttributesValidator.getValidator(new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .withType(UMessageType.PUBLISH) + .build()); + assert(response instanceof UAttributesValidator); + + UAttributesValidator invalid = UAttributesValidator.getValidator(new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .build()); + assert(invalid instanceof UAttributesValidator); + } + +} From 4bf89a8b15f849179a7584777b198cceca14b8ee Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 24 Aug 2023 14:43:42 -0400 Subject: [PATCH 03/52] Adding documentation Adding more README for how to use the SDK per package #17 --- README.adoc | 76 +++++-------------- .../eclipse/uprotocol/cloudevent/README.adoc | 21 +++++ .../org/eclipse/uprotocol/rpc/README.adoc | 7 ++ .../org/eclipse/uprotocol/uri/README.adoc | 51 +++++++++++++ .../eclipse/uprotocol/utransport/README.adoc | 7 ++ .../org/eclipse/uprotocol/uuid/README.adoc | 8 ++ 6 files changed, 115 insertions(+), 55 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/cloudevent/README.adoc create mode 100644 src/main/java/org/eclipse/uprotocol/rpc/README.adoc create mode 100644 src/main/java/org/eclipse/uprotocol/uri/README.adoc create mode 100644 src/main/java/org/eclipse/uprotocol/utransport/README.adoc create mode 100644 src/main/java/org/eclipse/uprotocol/uuid/README.adoc diff --git a/README.adoc b/README.adoc index 53c10e78..f3781eb8 100644 --- a/README.adoc +++ b/README.adoc @@ -1,17 +1,11 @@ -image:https://github.com/eclipse-uprotocol/.github/raw/main/logo/uprotocol_logo.png[alt=uProtocol,640] - -image:https://img.shields.io/badge/License-Apache%202.0-blue.svg[License,link=https://opensource.org/licenses/Apache-2.0] - = Eclipse uProtocol Java SDK :toc: == Overview -The main object of this module is to enable constructing and deconstructing uProtocol CloudEvents. - -The core module contains functional factory methods for creating CloudEvents as well as functional factory methods that make it more intuitive to create URIs that are used to configure source and sink (destination) elements in the uProtocol CloudEvents. +The purpose of this module is to provide language specific code that builds the various data types defined in . The SDK also defines https://github.com/eclipse-uprotocol/uprotocol-spec/tree/main[uProtocol Specifications]. -This module contains the data model structures as well as core functionality for building uProtocol CloudEvents and URIs for sink and source attributes. +The module contains factory methods and validators for all data types used in uProtocol. The SDKs are then used by the code generators to auto-populate service stubs with generated code that builds CloudEvents. For more information on auto-generating service stubs, please refer to http://github.com/eclipse-uprotocol/uprotocol[uProtocol Main Project] @@ -28,57 +22,29 @@ The SDKs are then used by the code generators to auto-populate service stubs wit ---- +=== Using the sdk -=== UriFactory - -Matches the uProtocol URI Format. and is used to define source and sink (destination) attributes of uProtocol CloudEvents. -The factory builds URIs. - -URI is used as a method to uniquely identify devices, services, and resources on the network. - -*An Uri is built from the following elements:* - -* *UAuthority* - represents the device and domain of the software, the deployment. You can specify local or remote options. -* *UEntity* - The Software Entity defines the software name and version. -* *UResource* - The resource of the software can be a service name, and instance in the service and the name of the protobuf IDL message. - -==== UAuthority - -An Authority consists of a device and a domain per uProtocol URI format. - -An Authority represents the deployment location of a specific Software Entity. - -==== UEntity - uE - -An Software Entity is a piece of software deployed somewhere on a device. The uE is used in the source and sink parts of communicating software. - -A uE that *publishes* events is a *Service* role. - -A uE that *consumes* events is an *Application* role. - -A uE may combine bother Service and Application roles. - - -==== UResource - -A service API - defined in the uE - has Resources and Methods. Both of these are represented by the UResource class. - -An UResource is something that can be manipulated/controlled/exposed by a service. - -Resources are unique when prepended with UAuthority that represents the device and Software Entity that represents the service. - -An Resource represents a resource from a Service such as "door" and an optional specific instance such as "front_left". -In addition, it can optionally contain the name of the resource Message type, such as "Door". +The SDK is composed of 4 main packages as shown in <> below: -The Message type matches the protobuf service IDL that defines structured data types. A message is a data structure type used to define data that is passed in events and rpc methods. +.SDK Packages +[#sdk-packages,width=100%,cols="15%,25%,60%"] +|=== +| Package | https://github.com/eclipse-uprotocol/uprotocol-spec[uprotocol-spec] | Purpose -=== CloudEventFactory -Factory class that builds the various types of CloudEvents for uProtocol (publish, notification, request, response) +| link:src/main/java/org/eclipse/uprotocol/uri/README.adoc[`uuri`] +| https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc[URI, UAthority, UEntity, UResource] +| Uniform Resource Identifier (RFC3986) used to address things (devices, software, methods, topics, etc...) on the network -== Examples +| link:src/main/java/org/eclipse/uprotocol/cloudevent/README.adoc[`cloudevent`] +| https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/cloudevents.adoc[uProtocol CloudEvents] +| Common way to represent uProtocol messages using CloudEvent data model -The SDK contains comprehensive tests, the best place to look at how all the APIs are used are at: +| link:src/main/java/org/eclipse/uprotocol/uuid/README.adoc[`uuid`] +| https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uuid.adoc[uProtocol UUIDs] +| Identifier used to uniquely identify messages that are sent between devices. also includes timestamp for the message -* link:src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java[UriFactoryTest.java] +| link:src/main/java/org/eclipse/uprotocol/utransport/README.adoc[`utransport`] +| https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/README.adoc[uP-L1 Specifications] +| Interface (and data model) used for bidirectional point-2-point communication between uEs. Interface is to be implemented by the different communication technologies (ex. Binder, MQTT, Zenoh, SOME/IP, DDS, HTTP, etc…​) -* link:src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java[CloudEventFactoryTest.java] +|=== \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/README.adoc b/src/main/java/org/eclipse/uprotocol/cloudevent/README.adoc new file mode 100644 index 00000000..cf1a4aea --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/README.adoc @@ -0,0 +1,21 @@ += uProtocol CloudEvents +:toc: +:sectnums: + + +== Overview + +https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/cloudevents.adoc[uProtocol CloudEvents] is a common message envelope that could be used to carry way to represent uProtocol transport layer information `UUri` (source), `UPayload`, and `UAttributes`. `CloudEvents` are used by a number of Device-2-Cloud and Cloud-2-Device based transports such as MQTT and HTTP, however it could also be used by any transport (ex. Binder). + +NOTE: CloudEvent is not, nor was not, meant to be _the_ only message format used below or above the transport layer. + +=== CloudEventFactory +Factory class that builds the various types of CloudEvents for uProtocol (publish, notification, request, response) + +== Examples + +The SDK contains comprehensive tests, the best place to look at how all the APIs are used are at: + +* link:src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java[UriFactoryTest.java] + +* link:src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java[CloudEventFactoryTest.java] diff --git a/src/main/java/org/eclipse/uprotocol/rpc/README.adoc b/src/main/java/org/eclipse/uprotocol/rpc/README.adoc new file mode 100644 index 00000000..5282d2e6 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/rpc/README.adoc @@ -0,0 +1,7 @@ += uProtocol Rpc Interfaces +:toc: +:sectnums: + +== Overview + +_comming soon_ diff --git a/src/main/java/org/eclipse/uprotocol/uri/README.adoc b/src/main/java/org/eclipse/uprotocol/uri/README.adoc new file mode 100644 index 00000000..fc205b9d --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/README.adoc @@ -0,0 +1,51 @@ += uProtocol URI +:toc: +:sectnums: + + +== Overview + +The following folder contains the data model, factory, and validators to implement https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc[uProtocol URI Specifications] + +Matches the uProtocol URI Format. and is used to define source and sink (destination) attributes of uProtocol. +The factory builds URIs. + +URI is used as a method to uniquely identify devices, services, and resources on the network. + +== UUri + +*An Uri is built from the following elements:* + +* *UAuthority* - represents the device and domain of the software, the deployment. You can specify local or remote options. +* *UEntity* - The Software Entity defines the software name and version. +* *UResource* - The resource of the software can be a service name, and instance in the service and the name of the protobuf IDL message. + +=== UAuthority + +An Authority consists of a device and a domain per uProtocol URI format. + +An Authority represents the deployment location of a specific Software Entity. + +=== UEntity - uE + +An Software Entity is a piece of software deployed somewhere on a device. The uE is used in the source and sink parts of communicating software. + +A uE that *publishes* events is a *Service* role. + +A uE that *consumes* events is an *Application* role. + +A uE may combine bother Service and Application roles. + + +=== UResource + +A service API - defined in the uE - has Resources and Methods. Both of these are represented by the UResource class. + +An UResource is something that can be manipulated/controlled/exposed by a service. + +Resources are unique when prepended with UAuthority that represents the device and Software Entity that represents the service. + +An Resource represents a resource from a Service such as "door" and an optional specific instance such as "front_left". +In addition, it can optionally contain the name of the resource Message type, such as "Door". + +The Message type matches the protobuf service IDL that defines structured data types. A message is a data structure type used to define data that is passed in events and rpc methods. \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/utransport/README.adoc b/src/main/java/org/eclipse/uprotocol/utransport/README.adoc new file mode 100644 index 00000000..e154d5d9 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/utransport/README.adoc @@ -0,0 +1,7 @@ += uProtocol Transport Interface & Data Model +:toc: +:sectnums: +:source-highlighter: prettify + +== Overview +The purpose of this moduel is to provide the Java implementation of https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/README.adoc[uTransport API & Data Model]. The transport API is used by all uE developers to send and receive messages across any transport. The interface is to be implemented by communication transport developers (i.e. developing a uTransport for SOME/IP, DDS, Zenoh, MQTT, etc...). diff --git a/src/main/java/org/eclipse/uprotocol/uuid/README.adoc b/src/main/java/org/eclipse/uprotocol/uuid/README.adoc new file mode 100644 index 00000000..e61f7ae2 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uuid/README.adoc @@ -0,0 +1,8 @@ += uProtocol UUID +:toc: +:sectnums: + +== Overview + +_comming soon_ + From ed8e57e75b2713200ecf79e76911b1486df1c5aa Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 24 Aug 2023 20:41:39 -0400 Subject: [PATCH 04/52] Added more Test coverage Also fixed some issues in UAttributes and the validator #17 --- .../utransport/datamodel/UAttributes.java | 8 +- .../validate/UAttributesValidator.java | 57 ++-- .../validator/UAttributesValidatorTest.java | 301 ++++++++++++++++++ 3 files changed, 339 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 5a3cf87f..129b6930 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -148,7 +148,7 @@ public Optional serializationHint() { * @return Returns an Optional destination URI attribute. */ public Optional sink() { - return sink == null || sink.isEmpty() ? Optional.empty() : Optional.of(sink); + return sink == null ? Optional.empty() : Optional.of(sink); } /** @@ -269,7 +269,7 @@ public UAttributesBuilder withSink(UUri sink) { * @param plevel the permission level of the message. * @return Returns the UAttributesBuilder with the configured plevel. */ - public UAttributesBuilder withPlevel(Integer plevel) { + public UAttributesBuilder withPermissionLevel(Integer plevel) { this.plevel = plevel; return this; } @@ -279,7 +279,7 @@ public UAttributesBuilder withPlevel(Integer plevel) { * @param commstatus the communication status of the message. * @return Returns the UAttributesBuilder with the configured commstatus. */ - public UAttributesBuilder withCommstatus(Integer commstatus) { + public UAttributesBuilder withCommStatus(Integer commstatus) { this.commstatus = commstatus; return this; } @@ -289,7 +289,7 @@ public UAttributesBuilder withCommstatus(Integer commstatus) { * @param reqid the request ID. * @return Returns the UAttributesBuilder with the configured reqid. */ - public UAttributesBuilder withReqid(UUID reqid) { + public UAttributesBuilder withReqId(UUID reqid) { this.reqid = reqid; return this; } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java index 34926e33..4cb3c9da 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java @@ -9,10 +9,10 @@ import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; +import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.uuid.factory.UUIDUtils; - -import com.google.rpc.Code; +import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; /** * Abstract class for validating UAttributes. @@ -67,32 +67,35 @@ public UStatus validate(UAttributes attributes) { validateCommStatus(attributes), validateTtl(attributes), validatePermissionLevel(attributes), - validateCorrelationId(attributes)) + validateReqId(attributes)) .filter(UStatus::isFailed) .map(UStatus::msg) .collect(Collectors.joining(",")); return errorMessage.isBlank() ? UStatus.ok() : - UStatus.failed("Invalid argument", Code.INVALID_ARGUMENT_VALUE); + UStatus.failed(errorMessage, Code.INVALID_ARGUMENT); } public UStatus validatePriority(UAttributes attributes) { - return attributes.priority() != null ? UStatus.ok() : UStatus.failed(); + return attributes.priority() != null ? UStatus.ok() : + UStatus.failed("Invalid Priority", Code.INVALID_ARGUMENT.value()); } public UStatus validateTtl(UAttributes attributes) { Optional ttl = attributes.ttl(); if (ttl.isPresent()) { - return ttl.get() > 0 ? UStatus.ok() : UStatus.failed(); + return ttl.get() > 0 ? UStatus.ok() : + UStatus.failed("Invalid TTL", Code.INVALID_ARGUMENT.value()); } return UStatus.ok(); } public UStatus validateId(UAttributes attributes) { try { - return UUIDUtils.isUuid(attributes.id()) ? UStatus.ok() : UStatus.failed(); + return UUIDUtils.isUuid(attributes.id()) ? UStatus.ok() : + UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); } catch (Exception e) { - return UStatus.failed(); + return UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); } } @@ -102,7 +105,8 @@ public UStatus validateId(UAttributes attributes) { * @return Returns a UStatus indicating if the Uri is valid or not. */ public UStatus validateSink(UAttributes attributes) { - if (!attributes.sink().isEmpty()){ + Optional sink = attributes.sink(); + if (sink.isPresent()) { return UriValidator.validate(attributes.sink().get()); } return UStatus.ok(); @@ -114,8 +118,12 @@ public UStatus validateSink(UAttributes attributes) { * @return Returns a UStatus indicating if the commStatus is valid or not. */ public UStatus validateCommStatus(UAttributes attributes) { - if (!attributes.commstatus().isEmpty()){ - return Code.forNumber(attributes.commstatus().get()) != null ? UStatus.ok() : UStatus.failed(); + Optional commStatus = attributes.commstatus(); + + if (commStatus.isPresent()) { + Optional code = Code.from(commStatus.get()); + return code.isPresent() ? UStatus.ok() : + UStatus.failed("Invalid Communication Status Code", Code.INVALID_ARGUMENT.value()); } return UStatus.ok(); } @@ -128,8 +136,8 @@ public UStatus validateCommStatus(UAttributes attributes) { public UStatus validatePermissionLevel(UAttributes attributes) { final Optional plevel = attributes.plevel(); if (plevel.isPresent()) { - - return plevel.get() > 0 ? UStatus.ok() : UStatus.failed(); + return plevel.get() >= 0 ? UStatus.ok() : + UStatus.failed("Invalid Permission Level", Code.INVALID_ARGUMENT.value()); } return UStatus.ok(); } @@ -139,11 +147,12 @@ public UStatus validatePermissionLevel(UAttributes attributes) { * @param attributes UAttributes to validate * @return Returns a UStatus indicating if the correlationId is valid or not. */ - public UStatus validateCorrelationId(UAttributes attributes) { + public UStatus validateReqId(UAttributes attributes) { final Optional correlationId = attributes.reqid(); if (correlationId.isPresent()) { - return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : UStatus.failed(); + return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : + UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); } return UStatus.ok(); } @@ -170,7 +179,7 @@ private static class Publish extends UAttributesValidator { */ @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.PUBLISH ? UStatus.ok() : UStatus.failed(); + return attributes.type() == UMessageType.PUBLISH ? UStatus.ok() : UStatus.failed("Wrong Attribute Type", Code.INVALID_ARGUMENT.value()); } } @@ -194,7 +203,7 @@ public UStatus validateSink(UAttributes attributes) { final Optional sink = attributes.sink(); if (!sink.isPresent()) { - return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT_VALUE); + return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value()); } return UriValidator.validateRpcResponse(sink.get()); } @@ -208,7 +217,7 @@ public UStatus validateSink(UAttributes attributes) { public UStatus validateTtl(UAttributes attributes) { final Optional ttl = attributes.ttl(); if (!ttl.isPresent()) { - return UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT_VALUE); + return UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT.value()); } else { return ttl.get() > 0 ? UStatus.ok() : UStatus.failed(); } @@ -223,7 +232,8 @@ private static class Response extends UAttributesValidator { @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.RESPONSE ? UStatus.ok() : UStatus.failed(); + return attributes.type() == UMessageType.RESPONSE ? UStatus.ok() : + UStatus.failed("Invalid Type", Code.INVALID_ARGUMENT.value()); } /** @@ -236,7 +246,7 @@ public UStatus validateSink(UAttributes attributes) { final Optional sink = attributes.sink(); if (!sink.isPresent()) { - return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT_VALUE); + return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value()); } return UriValidator.validateRpcMethod(sink.get()); } @@ -247,13 +257,14 @@ public UStatus validateSink(UAttributes attributes) { * @return Returns a UStatus indicating if the correlationId is valid or not. */ @Override - public UStatus validateCorrelationId(UAttributes attributes) { + public UStatus validateReqId(UAttributes attributes) { final Optional correlationId = attributes.reqid(); if (!correlationId.isPresent()) { - return UStatus.failed("Missing correlationId", Code.INVALID_ARGUMENT_VALUE); + return UStatus.failed("Missing correlationId", Code.INVALID_ARGUMENT.value()); } - return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : UStatus.failed(); + return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : + UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); } } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index 09e19627..b77a750d 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -22,14 +22,22 @@ package org.eclipse.uprotocol.utransport.validator; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import java.util.UUID; + +import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; import org.eclipse.uprotocol.utransport.datamodel.UPriority; import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; +import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; +import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; import org.eclipse.uprotocol.utransport.validate.UAttributesValidator; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import org.junit.jupiter.api.DisplayName; @@ -69,5 +77,298 @@ public void test_fetching_validator_for_valid_types() { .build()); assert(invalid instanceof UAttributesValidator); } + + @Test + @DisplayName("test validating invalid types") + public void test_validator_invalid_types() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .build(); + + final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Wrong Attribute Type"); + } + + @Test + @DisplayName("test validating_valid_publish_messagetypes") + public void test_validating_valid_publish_messagetypes() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .withType(UMessageType.PUBLISH) + .build(); + + final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals(status.msg(), "ok"); + } + + @Test + @DisplayName("test validating invalid priority attribute") + public void test_validating_invalid_priority_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withPriority(null) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + + final UStatus status = validator.validatePriority(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid Priority"); + } + + @Test + @DisplayName("test validating valid priority attribute") + public void test_validating_valid_priority_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withPriority(UPriority.LOW) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validatePriority(attributes); + assertEquals(status, UStatus.ok()); + } + + @Test + @DisplayName("test validating invalid ttl attribute") + public void test_validating_invalid_ttl_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withTtl(-1) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateTtl(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid TTL"); + } + + @Test + @DisplayName("test validating valid ttl attribute") + public void test_validating_valid_ttl_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withTtl(100) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateTtl(attributes); + assertEquals(status, UStatus.ok()); + } + + @Test + @DisplayName("test validating invalid id attribute") + public void test_validating_invalid_id_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withId(null) + .build(); + final UAttributes attributes1 = new UAttributesBuilder() + .withId(UUID.randomUUID()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + UStatus status = validator.validateId(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid UUID"); + + status = validator.validateId(attributes1); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid UUID"); + } + + @Test + @DisplayName("test validating valid id attribute") + public void test_validating_valid_id_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateId(attributes); + assertEquals(status, UStatus.ok()); + } + + @Test + @DisplayName("test validating invalid sink attribute") + public void test_validating_invalid_sink_attribute() { + final UUri uri = UriFactory.parseFromUri("//"); + final UAttributes attributes = new UAttributesBuilder() + .withSink(uri) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateSink(attributes); + + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Uri is configured to be remote and is missing uAuthority device name."); + } + + @Test + @DisplayName("test validating valid sink attribute") + public void test_validating_valid_sink_attribute() { + final UUri uri = UriFactory.parseFromUri("/haartley/1"); + final UAttributes attributes = new UAttributesBuilder() + .withSink(uri) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateSink(attributes); + assertEquals(status, UStatus.ok()); + } + + @Test + @DisplayName("test validating invalid ReqId attribute") + public void test_validating_invalid_ReqId_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withReqId(UUID.randomUUID()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateReqId(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid UUID"); + } + + @Test + @DisplayName("test validating valid ReqId attribute") + public void test_validating_valid_ReqId_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateReqId(attributes); + assertEquals(status, UStatus.ok()); + } + + + @Test + @DisplayName("test validating invalid PermissionLevel attribute") + public void test_validating_invalid_PermissionLevel_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withPermissionLevel(-1) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validatePermissionLevel(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid Permission Level"); + } + + @Test + @DisplayName("test validating valid PermissionLevel attribute") + public void test_validating_valid_PermissionLevel_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withPermissionLevel(0) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validatePermissionLevel(attributes); + assertEquals(status, UStatus.ok()); + } + + @Test + @DisplayName("test validating invalid commstatus attribute") + public void test_validating_invalid_commstatus_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withCommStatus(100) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateCommStatus(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid Communication Status Code"); + } + + @Test + @DisplayName("test validating valid commstatus attribute") + public void test_validating_valid_commstatus_attribute() { + final UAttributes attributes = new UAttributesBuilder() + .withCommStatus(Code.ABORTED.value()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validateCommStatus(attributes); + assertEquals(status, UStatus.ok()); + } + + + @Test + @DisplayName("test validating request message types") + public void test_validating_request_message_types() { + final UUri sink = UriFactory.parseFromUri("/hartley/1/rpc.response"); + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.NETWORK_CONTROL) + .withType(UMessageType.REQUEST) + .withSink(sink) + .withTtl(100) + .build(); + + final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals(status.msg(), "ok"); + } + + @Test + @DisplayName("test validating request validator using wrong messagetype") + public void test_validating_request_validator_with_wrong_messagetype() { + final UAttributes attributes = new UAttributesBuilder() + .withType(UMessageType.PUBLISH) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "failed,Invalid UUID,Missing Sink,Invalid Priority,Missing TTL"); + } + + @Test + @DisplayName("test validating publish validator with wrong messagetype") + public void test_validating_publish_validator_with_wrong_messagetype() { + final UAttributes attributes = new UAttributesBuilder() + .withType(UMessageType.REQUEST) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Wrong Attribute Type,Invalid UUID,Invalid Priority"); + } + + @Test + @DisplayName("test validating response validator with wrong messagetype") + public void test_validating_response_validator_with_wrong_messagetype() { + final UAttributes attributes = new UAttributesBuilder() + .withType(UMessageType.PUBLISH) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid Type,Invalid UUID,Missing Sink,Invalid Priority,Missing correlationId"); + } + } From b824eebd99cf1523074efe44f2bf7a3221fb6172 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Mon, 28 Aug 2023 11:41:41 -0400 Subject: [PATCH 05/52] Additional Test coverage --- .../validate/UAttributesValidator.java | 26 +++++- .../utransport/datamodel/UAttributeTest.java | 35 ++++++++ .../validator/UAttributesValidatorTest.java | 89 +++++++++++++++++-- 3 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java index 4cb3c9da..0b9961aa 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.utransport.validate; import java.util.Optional; @@ -9,7 +29,6 @@ import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; -import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.uuid.factory.UUIDUtils; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; @@ -190,7 +209,8 @@ private static class Request extends UAttributesValidator { @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.REQUEST ? UStatus.ok() : UStatus.failed(); + return attributes.type() == UMessageType.REQUEST ? UStatus.ok() : + UStatus.failed("Wrong Attribute Type", Code.INVALID_ARGUMENT.value()); } /** @@ -219,7 +239,7 @@ public UStatus validateTtl(UAttributes attributes) { if (!ttl.isPresent()) { return UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT.value()); } else { - return ttl.get() > 0 ? UStatus.ok() : UStatus.failed(); + return ttl.get() > 0 ? UStatus.ok() : UStatus.failed("Invalid TTL", Code.INVALID_ARGUMENT.value()); } } } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java new file mode 100644 index 00000000..1449303f --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.utransport.datamodel; + +import org.junit.Test; +import org.junit.jupiter.api.DisplayName; + + +public class UAttributeTest { + + @Test + @DisplayName("test UAttributesBuilder") + public void test_uattributesbuilder() { + + } +} diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index b77a750d..a2aed034 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -23,14 +23,12 @@ import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.UUID; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.factory.UriFactory; -import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; import org.eclipse.uprotocol.utransport.datamodel.UPriority; @@ -67,7 +65,7 @@ public void test_fetching_validator_for_valid_types() { UAttributesValidator response = UAttributesValidator.getValidator(new UAttributesBuilder() .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .withPriority(UPriority.LOW) - .withType(UMessageType.PUBLISH) + .withType(UMessageType.RESPONSE) .build()); assert(response instanceof UAttributesValidator); @@ -139,8 +137,8 @@ public void test_validating_valid_priority_attribute() { } @Test - @DisplayName("test validating invalid ttl attribute") - public void test_validating_invalid_ttl_attribute() { + @DisplayName("test validating publish invalid ttl attribute") + public void test_validating_publish_invalid_ttl_attribute() { final UAttributes attributes = new UAttributesBuilder() .withTtl(-1) .build(); @@ -153,7 +151,7 @@ public void test_validating_invalid_ttl_attribute() { } @Test - @DisplayName("test validating valid ttl attribute") + @DisplayName("test validating publish valid ttl attribute") public void test_validating_valid_ttl_attribute() { final UAttributes attributes = new UAttributesBuilder() .withTtl(100) @@ -338,9 +336,69 @@ public void test_validating_request_validator_with_wrong_messagetype() { final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "failed,Invalid UUID,Missing Sink,Invalid Priority,Missing TTL"); + assertEquals(status.msg(), "Wrong Attribute Type,Invalid UUID,Missing Sink,Invalid Priority,Missing TTL"); + } + + @Test + @DisplayName("test validating request validator using bad ttl") + public void test_validating_request_validator_with_wrong_bad_ttl() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withPriority(UPriority.NETWORK_CONTROL) + .withType(UMessageType.REQUEST) + .withTtl(-1) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid TTL"); } + @Test + @DisplayName("test validating response validator using bad ttl") + public void test_validating_response_validator_with_wrong_bad_ttl() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withPriority(UPriority.NETWORK_CONTROL) + .withTtl(-1) + .withType(UMessageType.RESPONSE) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid TTL"); + } + + @Test + @DisplayName("test validating response validator using bad UUID") + public void test_validating_response_validator_with_bad_reqid() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withPriority(UPriority.NETWORK_CONTROL) + .withTtl(100) + .withType(UMessageType.RESPONSE) + .withReqId(UUID.randomUUID()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status.msg(), "Invalid UUID"); + } + + @Test @DisplayName("test validating publish validator with wrong messagetype") public void test_validating_publish_validator_with_wrong_messagetype() { @@ -371,4 +429,21 @@ public void test_validating_response_validator_with_wrong_messagetype() { assertEquals(status.msg(), "Invalid Type,Invalid UUID,Missing Sink,Invalid Priority,Missing correlationId"); } + + @Test + @DisplayName("test validating request containing hint and token") + public void test_validating_request_containing_hint_and_token() { + final UAttributes attributes = new UAttributesBuilder() + .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPriority(UPriority.LOW) + .withType(UMessageType.PUBLISH) + .withHint(USerializationHint.JSON) + .withToken("null") + .build(); + + final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); + assert(validator instanceof UAttributesValidator); + final UStatus status = validator.validate(attributes); + assertEquals(status, UStatus.ok()); + } } From 301dcf75d772f83b35adead9bc1843483e8637a0 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 29 Aug 2023 23:42:24 -0400 Subject: [PATCH 06/52] Added the start of a Micro Uri --- .../uprotocol/uri/datamodel/UAuthority.java | 45 ++++++- .../uprotocol/uri/datamodel/UEntity.java | 29 +++- .../uprotocol/uri/datamodel/UResource.java | 47 ++++++- .../uprotocol/uri/factory/UriFactory.java | 124 ++++++++++++++++-- 4 files changed, 223 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 98be22e6..4f3e8c4a 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -21,6 +21,7 @@ package org.eclipse.uprotocol.uri.datamodel; +import java.net.InetAddress; import java.util.Objects; import java.util.Optional; @@ -53,6 +54,13 @@ public class UAuthority { // TODO add user information - what is this used for? make sure it is part of the domain. + + /** + * The device IP address. + */ + private final InetAddress address; + + /** * Constructor. * @@ -63,9 +71,24 @@ public class UAuthority { private UAuthority(String device, String domain, boolean markedRemote) { this.device = device == null ? null : device.toLowerCase(); this.domain = domain == null ? null : domain.toLowerCase(); + this.address = null; this.markedRemote = markedRemote; } + /** + * using IP Address. + * + * @param address The device IP address. + * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. + */ + private UAuthority(InetAddress address, boolean markedRemote) { + this.device = null; + this.domain = null; + this.address = address; + this.markedRemote = markedRemote; + } + + /** * Static factory method for creating a local authority.
* A local uri does not contain an authority and looks like this: @@ -88,6 +111,15 @@ public static UAuthority remote(String device, String domain) { return new UAuthority(device, domain, true); } + /** + * Static factory method for creating a remote authority.
+ * @param address The device an software entity is deployed on + * @return returns a remote authority that contains the device and the domain. + */ + public static UAuthority remote(InetAddress device) { + return new UAuthority(device, true); + } + /** * Static factory method for creating an empty authority, to avoid working with null
* @return Returns an empty altifi authority that has no domain or device information. @@ -124,6 +156,14 @@ public Optional domain() { return domain == null || domain.isBlank() ? Optional.empty() : Optional.of(domain); } + + /** + * @return Returns the device IP address. + */ + public Optional address() { + return Optional.ofNullable(address); + } + /** * @return Returns the explicitly configured remote deployment. */ @@ -137,12 +177,12 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; UAuthority that = (UAuthority) o; return markedRemote == that.markedRemote && Objects.equals(device, that.device) - && Objects.equals(domain, that.domain); + && Objects.equals(domain, that.domain) && Objects.equals(address, that.address); } @Override public int hashCode() { - return Objects.hash(device, domain, markedRemote); + return Objects.hash(device, domain, address, markedRemote); } @Override @@ -150,6 +190,7 @@ public String toString() { return "UAuthority{" + "device='" + device + '\'' + ", domain='" + domain + '\'' + + ", address='" + address + '\'' + ", markedRemote=" + markedRemote + '}'; } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 4ff8ab7a..06af3754 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -37,6 +37,19 @@ public class UEntity { private final String name; private final String version; + private final Integer id; + + /** + * Build an Software Entity that represents a communicating piece of software in the Ultiverse. + * @param name The name of the software such as petpp or body.access. + * @param version The software version. If not supplied, the latest version of the service will be used. + */ + public UEntity(String name, String version, Integer id) { + Objects.requireNonNull(name, " Software Entity must have a name"); + this.name = name; + this.id = id; + this.version = version; + } /** * Build an Software Entity that represents a communicating piece of software in the Ultiverse. @@ -46,6 +59,7 @@ public class UEntity { public UEntity(String name, String version) { Objects.requireNonNull(name, " Software Entity must have a name"); this.name = name; + this.id = null; this.version = version; } @@ -89,22 +103,31 @@ public Optional version() { return version == null || version.isBlank() ? Optional.empty() : Optional.of(version); } + /** + * @return Returns the software id if it exists. + * + */ + public Optional id() { + return Optional.ofNullable(id); + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UEntity that = (UEntity) o; - return Objects.equals(name, that.name) && Objects.equals(version, that.version); + return Objects.equals(name, that.name) && Objects.equals(version, that.version) && Objects.equals(id, that.id); } @Override public int hashCode() { - return Objects.hash(name, version); + return Objects.hash(name, version, id); } @Override public String toString() { return "UEntity{" + "name='" + name + '\'' - + ", version='" + (version == null ? "latest" : version) + '\'' + '}'; + + ", version='" + (version == null ? "latest" : version) + '\'' + + ", id='" + (id == null ? "unknown" : id) + '\'' + '}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 5d70bf12..6fdc0351 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -33,9 +33,11 @@ */ public class UResource { - private static final UResource EMPTY = new UResource("", null,null); + private static final UResource EMPTY = new UResource("", null,null, 0); - private static final UResource RESPONSE = new UResource("rpc", "response",null); + private static final UResource RESPONSE = new UResource("rpc", "response",null, 0); + + private static final String UNKNOWN_NAME = new String("unknown"); private final String name; @@ -43,6 +45,8 @@ public class UResource { private final String message; + private final Integer id; + //TODO when message is empty - try and infer it from the name "door" -> "Door" /** @@ -53,10 +57,36 @@ public class UResource { * A message is a data structure type used to define data that is passed in events and rpc methods. */ public UResource(String name, String instance, String message) { + this(name, instance, message, 0); + } + + /** + * Create an Resource. The resource is something that is manipulated by a service such as a door. + * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. + * @param instance An instance of a resource such as front_left. + * @param message The Message type matches the protobuf service IDL message name that defines structured data types. + * A message is a data structure type used to define data that is passed in events and rpc methods. + */ + public UResource(String name, String instance, String message, Integer id) { Objects.requireNonNull(name, " Resource must have a name."); this.name = name; this.instance = instance; this.message = message; + this.id = id; + } + + + /** + * Static factory method for creating an Resource using the resource id. + * @param id The id of the resource. + * @return Returns an UResource with the resource id where the name, instance and message are empty. + */ + public static UResource fromId(Integer id) { + Objects.requireNonNull(id, "id Required"); + if (id == 0) { + return new UResource(new String("rpc"), new String("response"), null, id); + } + return new UResource(UNKNOWN_NAME, null, null, id); } /** @@ -127,6 +157,13 @@ public String name() { return name; } + /** + * @return Returns the resource id if it exists. + */ + public Integer id() { + return id; + } + /** * Support for building the name attribute in many protobuf Message objects. * Will build a string with the name and instance with a dot delimiter, only if the instance exists. @@ -162,12 +199,13 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UResource that = (UResource) o; - return Objects.equals(name, that.name) && Objects.equals(instance, that.instance) && Objects.equals(message, that.message); + return Objects.equals(name, that.name) && Objects.equals(instance, that.instance) && + Objects.equals(message, that.message) && Objects.equals(id, that.id); } @Override public int hashCode() { - return Objects.hash(name, instance, message); + return Objects.hash(name, instance, message, id); } @Override @@ -176,6 +214,7 @@ public String toString() { "name='" + name + '\'' + ", instance='" + instance + '\'' + ", message='" + message + '\'' + + ", id='" + id + '\'' + '}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index e9e92a47..ab0570f2 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -26,7 +26,12 @@ import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -50,7 +55,7 @@ static String buildUProtocolUri(UUri Uri) { StringBuilder sb = new StringBuilder(); - sb.append(buildAuthorityPartOfUri(Uri.uAuthority())); + sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), false)); if (Uri.uAuthority().isMarkedRemote()) { sb.append("/"); @@ -60,9 +65,9 @@ static String buildUProtocolUri(UUri Uri) { return sb.toString(); } - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity())); + sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), false)); - sb.append(buildResourcePartOfUri(Uri.uResource())); + sb.append(buildResourcePartOfUri(Uri.uResource(), false)); return sb.toString().replaceAll("/+$", ""); } @@ -83,6 +88,92 @@ static String buildUProtocolUri(UAuthority uAuthority, UEntity uEntity, UResourc } + /** + * Create the uProtocol URI string for source sink and topics in short form. + * + * @param Uri The URI data object. + * @return Returns the short form uProtocol URI string from an URI data object + */ + static String buildUProtocolShortUri(UUri Uri) { + if (Uri == null || Uri.isEmpty()) { + return new String(); + } + + StringBuilder sb = new StringBuilder(); + + sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), true)); + + if (Uri.uAuthority().isMarkedRemote()) { + sb.append("/"); + } + + if (Uri.uEntity().isEmpty()) { + return sb.toString(); + } + + sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), true)); + + sb.append(buildResourcePartOfUri(Uri.uResource(), true)); + + return sb.toString().replaceAll("/+$", ""); + } + + /** + * Create uProtocol Micro-URI to represent the URI in a byte array in lieu of a string + * + * IPv4 Micro URI: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | URI version | unused | uResource.id() | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | uAuthority.address() | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | uE.id() |uE.ver() MAJOR |uE.ver() MINOR | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + * IPv6 Micro URI: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | URI version | unused | uResource.id() | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | uAuthority.address() | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | uEntity.id() |uE.ver() MAJOR |uE.ver() MINOR | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * @param Uri The URI data object. + * @return Returns the short form uProtocol URI string from an URI data object + */ + static byte[] buildUProtocolMicroUri(UUri Uri) { + if (Uri == null || Uri.isEmpty()) { + return new byte[0]; + } + + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + os.write((byte)1); // Version + os.write(0); // Unused + os.write(Uri.uResource().id()); // uResource ID + os.write(Uri.uAuthority().address().get().getAddress()); // uAuthority Address + os.write(Uri.uEntity().id().get().shortValue()); // uEntity ID + + // TODO: Convert the uE.version() to MAJOR & MINOR in the URI + //final Float version = Float.valueOf(Uri.uEntity().version().orElse("0.0")); + return os.toByteArray(); + } + catch (IOException e) { + return new byte[0]; + } + } + /** * Create the uProtocol URI string for the source or sink of the CloudEvent that represents an RPC request. * Use this to generate the URI for the software entity who originated the RPC call. @@ -96,11 +187,11 @@ static String buildUriForRpc(UAuthority uAuthority, UEntity uEntitySource) { StringBuilder sb = new StringBuilder(); - sb.append(buildAuthorityPartOfUri(uAuthority)); + sb.append(buildAuthorityPartOfUri(uAuthority, false)); if (uAuthority.isMarkedRemote()) { sb.append("/"); } - sb.append(buildSoftwareEntityPartOfUri(uEntitySource)); + sb.append(buildSoftwareEntityPartOfUri(uEntitySource, false)); sb.append("/"); sb.append(UResource.response().nameWithInstance()); @@ -119,22 +210,22 @@ static String buildUriForRpc(UAuthority uAuthority, static String buildMethodUri(UAuthority uAuthority, UEntity uEntity, String methodName) { StringBuilder sb = new StringBuilder(); - sb.append(buildAuthorityPartOfUri(uAuthority)); + sb.append(buildAuthorityPartOfUri(uAuthority, false)); if (uAuthority.isMarkedRemote()) { sb.append("/"); } - sb.append(buildSoftwareEntityPartOfUri(uEntity)); + sb.append(buildSoftwareEntityPartOfUri(uEntity, false)); - sb.append(buildResourcePartOfUri(UResource.forRpc(methodName))); + sb.append(buildResourcePartOfUri(UResource.forRpc(methodName), false)); return sb.toString(); } - private static String buildResourcePartOfUri(UResource uResource) { + private static String buildResourcePartOfUri(UResource uResource, boolean shortUri) { if (uResource.isEmpty()) { return ""; } - StringBuilder sb = new StringBuilder("/").append(uResource.name()); + StringBuilder sb = new StringBuilder("/").append(shortUri ? uResource.id() : uResource.name()); uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); uResource.message().ifPresent(message -> sb.append("#").append(message)); @@ -145,8 +236,8 @@ private static String buildResourcePartOfUri(UResource uResource) { * Create the service part of the uProtocol URI from an software entity object. * @param use Software Entity representing a service or an application. */ - private static String buildSoftwareEntityPartOfUri(UEntity use) { - StringBuilder sb = new StringBuilder(use.name().trim()); + private static String buildSoftwareEntityPartOfUri(UEntity use, boolean shortUri) { + StringBuilder sb = new StringBuilder(shortUri? use.id().toString() : use.name().trim()); sb.append("/"); use.version().ifPresent(sb::append); @@ -159,11 +250,18 @@ private static String buildSoftwareEntityPartOfUri(UEntity use) { * @param Authority represents the deployment location of a specific Software Entity in the Ultiverse. * @return Returns the String representation of the Authority in the uProtocol URI. */ - private static String buildAuthorityPartOfUri(UAuthority Authority) { + private static String buildAuthorityPartOfUri(UAuthority Authority, boolean shortUri) { if (Authority.isLocal()) { return "/"; } StringBuilder partialURI = new StringBuilder("//"); + if (shortUri) { + final Optional maybeAddress = Authority.address(); + if (maybeAddress.isPresent()) { + partialURI.append(maybeAddress.get().getHostAddress()); + } + return partialURI.toString(); + } final Optional maybeDevice = Authority.device(); final Optional maybeDomain = Authority.domain(); From 1594da87d2ffb4d29a4efd78795db12d37e6f424 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 30 Aug 2023 13:22:54 -0400 Subject: [PATCH 07/52] Added UUri id --- .../eclipse/uprotocol/uri/datamodel/UUri.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index f354ed2d..df5190e8 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -24,6 +24,7 @@ import org.eclipse.uprotocol.uri.factory.UriFactory; import java.util.Objects; +import java.util.Optional; /** * Data representation of an URI. @@ -46,6 +47,9 @@ public class UUri { private transient String uProtocolUri; + // Transport specific ID + private transient Integer id; + /** * Create a full URI. * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. @@ -142,4 +146,16 @@ public String toString() { ", uResource=" + uResource + '}'; } + + /** + * Method to get/set the ID used to represent the UUri as an ID in the transport layer. + * @param id The ID used to represent the UUri as an ID in the transport layer. + * @return Returns the ID used to represent the UUri as an ID in the transport layer. + */ + public Optional id(Optional id) { + if (id.isPresent()) { + this.id = id.get(); + } + return Optional.of(this.id); + } } From cf189518919aa8baf89ecb9de8903f881c5ddf1d Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 30 Aug 2023 16:53:11 -0400 Subject: [PATCH 08/52] Finished the micro Uri Still have to fix build and add lots of test cases!!! --- .../uprotocol/uri/datamodel/UEntity.java | 6 +- .../uprotocol/uri/datamodel/UResource.java | 16 +-- .../uprotocol/uri/factory/UriFactory.java | 103 ++++++++++-------- 3 files changed, 71 insertions(+), 54 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 06af3754..c7496533 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -37,14 +37,14 @@ public class UEntity { private final String name; private final String version; - private final Integer id; + private final Short id; /** * Build an Software Entity that represents a communicating piece of software in the Ultiverse. * @param name The name of the software such as petpp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. */ - public UEntity(String name, String version, Integer id) { + public UEntity(String name, String version, Short id) { Objects.requireNonNull(name, " Software Entity must have a name"); this.name = name; this.id = id; @@ -107,7 +107,7 @@ public Optional version() { * @return Returns the software id if it exists. * */ - public Optional id() { + public Optional id() { return Optional.ofNullable(id); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 6fdc0351..68ff1541 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -33,9 +33,9 @@ */ public class UResource { - private static final UResource EMPTY = new UResource("", null,null, 0); + private static final UResource EMPTY = new UResource("", null,null, null); - private static final UResource RESPONSE = new UResource("rpc", "response",null, 0); + private static final UResource RESPONSE = new UResource("rpc", "response",null, Short.valueOf((short)0)); private static final String UNKNOWN_NAME = new String("unknown"); @@ -45,7 +45,7 @@ public class UResource { private final String message; - private final Integer id; + private final Short id; //TODO when message is empty - try and infer it from the name "door" -> "Door" @@ -57,7 +57,7 @@ public class UResource { * A message is a data structure type used to define data that is passed in events and rpc methods. */ public UResource(String name, String instance, String message) { - this(name, instance, message, 0); + this(name, instance, message, Short.valueOf((short)0)); } /** @@ -67,7 +67,7 @@ public UResource(String name, String instance, String message) { * @param message The Message type matches the protobuf service IDL message name that defines structured data types. * A message is a data structure type used to define data that is passed in events and rpc methods. */ - public UResource(String name, String instance, String message, Integer id) { + public UResource(String name, String instance, String message, Short id) { Objects.requireNonNull(name, " Resource must have a name."); this.name = name; this.instance = instance; @@ -81,7 +81,7 @@ public UResource(String name, String instance, String message, Integer id) { * @param id The id of the resource. * @return Returns an UResource with the resource id where the name, instance and message are empty. */ - public static UResource fromId(Integer id) { + public static UResource fromId(Short id) { Objects.requireNonNull(id, "id Required"); if (id == 0) { return new UResource(new String("rpc"), new String("response"), null, id); @@ -160,8 +160,8 @@ public String name() { /** * @return Returns the resource id if it exists. */ - public Integer id() { - return id; + public Optional id() { + return Optional.of(id); } /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index ab0570f2..2c27cae5 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -28,21 +28,21 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.net.Inet6Address; import java.net.InetAddress; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** - * A factory is a part of the software has methods to generate concrete objects, usually of the same type or interface.
- * The URI Factory generates an URI. + * UUri Factory used to build different types of UUri (long, short, micro), and UUri objects themselves + * for the various use cases found in uProtocol specifications. + * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ public interface UriFactory { /** - * Create the uProtocol URI string for source sink and topics from an URI. + * Build a Long-URI string from the separate parts of an URI. * * @param Uri The URI data object. * @return Returns the uProtocol URI string from an URI data object @@ -73,7 +73,7 @@ static String buildUProtocolUri(UUri Uri) { } /** - * Create the uProtocol URI string for source sink and topics from the separate parts + * Build a Long-Uri string using the separate parts of an URI. * of an URI. * * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. @@ -89,7 +89,7 @@ static String buildUProtocolUri(UAuthority uAuthority, UEntity uEntity, UResourc /** - * Create the uProtocol URI string for source sink and topics in short form. + * Build a Short-Uri string from a UUri object * * @param Uri The URI data object. * @return Returns the short form uProtocol URI string from an URI data object @@ -119,35 +119,22 @@ static String buildUProtocolShortUri(UUri Uri) { } /** - * Create uProtocol Micro-URI to represent the URI in a byte array in lieu of a string - * - * IPv4 Micro URI: - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | URI version | unused | uResource.id() | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | uAuthority.address() | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | uE.id() |uE.ver() MAJOR |uE.ver() MINOR | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * - * IPv6 Micro URI: - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | URI version | unused | uResource.id() | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * | uAuthority.address() | - * | | - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | uEntity.id() |uE.ver() MAJOR |uE.ver() MINOR | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * Build a Short-Uri string using the separate parts of an URI. + * of an URI. + * + * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @param uEntity The Software Entity in the role of a service or in the role of an application. + * @param uResource The resource is something that is manipulated by a service such as a Door. + * + * @return Returns the uProtocol URI string from an URI data object + * that can be used as a sink or a source in a uProtocol publish communication. + */ + static String buildUProtocolShortUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { + return buildUProtocolShortUri(new UUri(uAuthority, uEntity, uResource)); + } + + /** + * Build a Micro-URI byte[] using a passed UUri object * * @param Uri The URI data object. * @return Returns the short form uProtocol URI string from an URI data object @@ -158,15 +145,45 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { } try { + Optional maybeAddress = Uri.uAuthority().address(); + Optional maybeUeId = Uri.uEntity().id(); + Optional maybeUResourceId = Uri.uResource().id(); + Optional maybeUEntityId = Uri.uEntity().version(); + if (!maybeAddress.isPresent() || !maybeUeId.isPresent() || + !maybeUResourceId.isPresent() || !maybeUEntityId.isPresent()) { + return new byte[0]; + } + ByteArrayOutputStream os = new ByteArrayOutputStream(); - os.write((byte)1); // Version - os.write(0); // Unused - os.write(Uri.uResource().id()); // uResource ID - os.write(Uri.uAuthority().address().get().getAddress()); // uAuthority Address - os.write(Uri.uEntity().id().get().shortValue()); // uEntity ID + // UP_VERSION + os.write(0x1); + + // IPV + os.write(maybeAddress.get() instanceof Inet6Address ? 1<<7 : 0); + + // URESOURCE_ID + os.write(maybeUResourceId.get()); + + // UAUTHORITY_ADDRESS + os.write(maybeAddress.get().getAddress()); + + // UENTITY_ID + os.write(maybeUeId.get()); - // TODO: Convert the uE.version() to MAJOR & MINOR in the URI - //final Float version = Float.valueOf(Uri.uEntity().version().orElse("0.0")); + // UENTITY_VERSION + String version = Uri.uEntity().version().get(); + if (version.isEmpty()) { + os.write(Short.MAX_VALUE); + } else { + String[] parts = Uri.uEntity().version().get().split("\\."); + if (parts.length > 1) { + final short ver = (short)((Integer.parseInt(parts[0]) << 11) & Integer.parseInt(parts[1])); + os.write(ver); + } else { + os.write(0); + os.write(Integer.parseInt(parts[0])); + } + } return os.toByteArray(); } catch (IOException e) { From 96db5b66da25b5ea8d05727bf4f697d82f5aedc1 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 31 Aug 2023 22:22:44 -0400 Subject: [PATCH 09/52] Many more changes Various fixes, additional test cases, and code that converts to and from micro Uri format. --- .../uprotocol/uri/datamodel/UAuthority.java | 28 ++- .../uprotocol/uri/datamodel/UEntity.java | 19 +- .../uprotocol/uri/datamodel/UResource.java | 14 +- .../eclipse/uprotocol/uri/datamodel/UUri.java | 8 +- .../uprotocol/uri/factory/UriFactory.java | 113 ++++++++-- .../uprotocol/uri/validator/UriValidator.java | 11 + .../uri/datamodel/UAuthorityTest.java | 54 ++++- .../uprotocol/uri/datamodel/UEntityTest.java | 28 ++- .../uri/datamodel/UResourceTest.java | 78 ++++++- .../uprotocol/uri/datamodel/UUriTest.java | 34 ++- .../uprotocol/uri/factory/UriFactoryTest.java | 196 ++++++++++++++++++ .../uri/validator/UriValidatorTest.java | 10 +- .../validator/UAttributesValidatorTest.java | 2 +- 13 files changed, 534 insertions(+), 61 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 4f3e8c4a..2ec2a928 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -22,6 +22,7 @@ package org.eclipse.uprotocol.uri.datamodel; import java.net.InetAddress; +import java.util.Arrays; import java.util.Objects; import java.util.Optional; @@ -139,7 +140,7 @@ public boolean isRemote() { * @return returns true if this authority is local, meaning does not contain a device or a domain. */ public boolean isLocal() { - return domain().isEmpty() && device().isEmpty(); + return domain().isEmpty() && device().isEmpty() && address().isEmpty(); } /** @@ -194,4 +195,29 @@ public String toString() { ", markedRemote=" + markedRemote + '}'; } + + /** + * The type of address used for Micro URI. + */ + public enum AddressType { + LOCAL(0), + IPv4(1), + IPv6(2); + + private final int value; + + AddressType(int value) { + this.value = value; + } + + int getValue() { + return value; + } + + public static Optional from(int value) { + return Arrays.stream(AddressType.values()) + .filter(p -> p.getValue() == value) + .findAny(); + } + } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index c7496533..e8ffa80c 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -25,12 +25,11 @@ import java.util.Optional; /** - * Data representation of an Software Entity - USE
- * Matches the first part of the path part <app|service>/<version> in SDV-202 uProtocol Format
- * An Software Entity is a piece of software deployed somewhere on a uDevice in the Ultiverse.
- * The Software Entity is used in the source and sink parts of communicating software in the Ultiverse.
- * A USE that publishes events is a Service role.
- * A USE that consumes events is an Application role. + * Data representation of an Software Entity - uE
+ * An Software Entity is a piece of software deployed somewhere on a uDevice.
+ * The Software Entity is used in the source and sink parts of communicating software.
+ * A uE that publishes events is a Service role.
+ * A uE that consumes events is an Application role. */ public class UEntity { private static final UEntity EMPTY = new UEntity("", null); @@ -40,7 +39,7 @@ public class UEntity { private final Short id; /** - * Build an Software Entity that represents a communicating piece of software in the Ultiverse. + * Build an Software Entity that represents a communicating piece of software. * @param name The name of the software such as petpp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. */ @@ -52,7 +51,7 @@ public UEntity(String name, String version, Short id) { } /** - * Build an Software Entity that represents a communicating piece of software in the Ultiverse. + * Build an Software Entity that represents a communicating piece of software. * @param name The name of the software such as petpp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. */ @@ -64,7 +63,7 @@ public UEntity(String name, String version) { } /** - * Static factory method for creating a USE using the application or service name. + * Static factory method for creating a uE using the application or service name. * @param name The application or service name, such as petapp or body.access. * @return Returns an UEntity with the name where the version is the latest version of the service. */ @@ -72,6 +71,7 @@ public static UEntity fromName(String name) { return new UEntity(name, null); } + /** * Static factory method for creating an empty software entity, to avoid working with null
* @return Returns an empty software entity that has a blank name and no version information. @@ -88,6 +88,7 @@ public boolean isEmpty() { return name.isBlank() && version().isEmpty(); } + /** * @return Returns the name of the software such as petpp or body.access. */ diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 68ff1541..a941c397 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -47,8 +47,6 @@ public class UResource { private final Short id; - //TODO when message is empty - try and infer it from the name "door" -> "Door" - /** * Create an Resource. The resource is something that is manipulated by a service such as a door. * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. @@ -57,7 +55,7 @@ public class UResource { * A message is a data structure type used to define data that is passed in events and rpc methods. */ public UResource(String name, String instance, String message) { - this(name, instance, message, Short.valueOf((short)0)); + this(name, instance, message, null); } /** @@ -72,7 +70,11 @@ public UResource(String name, String instance, String message, Short id) { this.name = name; this.instance = instance; this.message = message; - this.id = id; + if (name.equals("rpc") && instance != null && instance.equals("response")) { + this.id = Short.valueOf((short)0); + } else { + this.id = id; + } } @@ -161,7 +163,7 @@ public String name() { * @return Returns the resource id if it exists. */ public Optional id() { - return Optional.of(id); + return Optional.ofNullable(id); } /** @@ -214,7 +216,7 @@ public String toString() { "name='" + name + '\'' + ", instance='" + instance + '\'' + ", message='" + message + '\'' + - ", id='" + id + '\'' + + ", id='" + (id == null ? "unknown" : id) + '\'' + '}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index df5190e8..b2a09ed7 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -152,10 +152,10 @@ public String toString() { * @param id The ID used to represent the UUri as an ID in the transport layer. * @return Returns the ID used to represent the UUri as an ID in the transport layer. */ - public Optional id(Optional id) { - if (id.isPresent()) { - this.id = id.get(); + public Optional id(Integer id) { + if (id != null) { + this.id = id; } - return Optional.of(this.id); + return Optional.ofNullable(this.id); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index 2c27cae5..a14d56f6 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -25,9 +25,11 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.datamodel.UAuthority.AddressType; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.util.Arrays; @@ -107,7 +109,7 @@ static String buildUProtocolShortUri(UUri Uri) { sb.append("/"); } - if (Uri.uEntity().isEmpty()) { + if (Uri.uEntity().id().isEmpty()) { return sb.toString(); } @@ -148,9 +150,7 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { Optional maybeAddress = Uri.uAuthority().address(); Optional maybeUeId = Uri.uEntity().id(); Optional maybeUResourceId = Uri.uResource().id(); - Optional maybeUEntityId = Uri.uEntity().version(); - if (!maybeAddress.isPresent() || !maybeUeId.isPresent() || - !maybeUResourceId.isPresent() || !maybeUEntityId.isPresent()) { + if (!maybeUeId.isPresent() || !maybeUResourceId.isPresent()) { return new byte[0]; } @@ -158,30 +158,40 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { // UP_VERSION os.write(0x1); - // IPV - os.write(maybeAddress.get() instanceof Inet6Address ? 1<<7 : 0); + // TYPE + if (Uri.uAuthority().isLocal()) { + os.write(0x0); + } else { + os.write(maybeAddress.get() instanceof Inet4Address ? 1 : 2); + } // URESOURCE_ID + os.write(maybeUResourceId.get()>>8); os.write(maybeUResourceId.get()); // UAUTHORITY_ADDRESS - os.write(maybeAddress.get().getAddress()); + if (!Uri.uAuthority().isLocal()) { + os.write(maybeAddress.get().getAddress()); + } // UENTITY_ID + os.write(maybeUeId.get()>>8); os.write(maybeUeId.get()); // UENTITY_VERSION - String version = Uri.uEntity().version().get(); + String version = Uri.uEntity().version().orElse(""); if (version.isEmpty()) { - os.write(Short.MAX_VALUE); + os.write((byte)Short.MAX_VALUE>>8); + os.write((byte)Short.MAX_VALUE); } else { - String[] parts = Uri.uEntity().version().get().split("\\."); + String[] parts = version.split("\\."); if (parts.length > 1) { - final short ver = (short)((Integer.parseInt(parts[0]) << 11) & Integer.parseInt(parts[1])); - os.write(ver); + int major = (Integer.parseInt(parts[0]) << 3) + (Integer.parseInt(parts[1]) >> 8); + os.write((byte)major); + os.write((byte)Integer.parseInt(parts[1])); } else { + os.write(Integer.parseInt(parts[0])<<3); os.write(0); - os.write(Integer.parseInt(parts[0])); } } return os.toByteArray(); @@ -242,9 +252,14 @@ private static String buildResourcePartOfUri(UResource uResource, boolean shortU if (uResource.isEmpty()) { return ""; } - StringBuilder sb = new StringBuilder("/").append(shortUri ? uResource.id() : uResource.name()); - uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); - uResource.message().ifPresent(message -> sb.append("#").append(message)); + StringBuilder sb = new StringBuilder("/"); + if (shortUri) { + uResource.id().ifPresent(sb::append); + } else { + sb.append(uResource.name()); + uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); + uResource.message().ifPresent(message -> sb.append("#").append(message)); + } return sb.toString(); } @@ -254,7 +269,7 @@ private static String buildResourcePartOfUri(UResource uResource, boolean shortU * @param use Software Entity representing a service or an application. */ private static String buildSoftwareEntityPartOfUri(UEntity use, boolean shortUri) { - StringBuilder sb = new StringBuilder(shortUri? use.id().toString() : use.name().trim()); + StringBuilder sb = new StringBuilder(shortUri? use.id().get().toString() : use.name().trim()); sb.append("/"); use.version().ifPresent(sb::append); @@ -292,7 +307,7 @@ private static String buildAuthorityPartOfUri(UAuthority Authority, boolean shor } /** - * Create an URI data object from a uProtocol string. + * Create an URI data object from a uProtocol string (long or short). * @param uProtocolUri A String uProtocol URI. * @return Returns an URI data object. */ @@ -358,7 +373,15 @@ static UUri parseFromUri(String uProtocolUri) { } - return new UUri(uAuthority, new UEntity(useName, useVersion), uResource); + Short maybeUeId = null; + if (!useName.isEmpty()) { + try { + maybeUeId = Short.parseShort(useName); + } catch (NumberFormatException e) { + maybeUeId = null; + } + } + return new UUri(uAuthority, new UEntity(useName, useVersion, maybeUeId), uResource); } private static UResource buildResource(String resourceString) { @@ -371,4 +394,56 @@ private static UResource buildResource(String resourceString) { return new UResource(resourceName, resourceInstance, resourceMessage); } + + /** + * Create an URI data object from a uProtocol micro URI. + * @param microUri A byte[] uProtocol micro URI. + * @return Returns an URI data object. + */ + static UUri parseFromMicroUri(byte[] microUri) { + if (microUri == null || microUri.length < 8 ) { + return UUri.empty(); + } + + // Need to be version 1 + if (microUri[0] != 0x1) { + return UUri.empty(); + } + + int uResourceId = ((microUri[2] & 0xFF) << 8) | (microUri[3] & 0xFF); + + Optional maybeAddress = Optional.empty(); + + Optional type = AddressType.from(microUri[1]); + + if (!type.isPresent()) { + return UUri.empty(); + } + + int index = 4; + if (!(type.get() == AddressType.LOCAL)) { + try { + maybeAddress = Optional.of(InetAddress.getByAddress( + Arrays.copyOfRange(microUri, index, (type.get() == AddressType.IPv4) ? 8 : 20))); + } catch (Exception e) { + maybeAddress = Optional.empty(); + } + index += type.get() == AddressType.IPv4 ? 4 : 16; + } + + int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); + + int ueVersion = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); + + String ueVersionString = String.valueOf(ueVersion >> 11); + if ((ueVersion & 0x7FF) != 0) { + ueVersionString += "." + (ueVersion & 0x7FF); + } + + return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), + new UEntity("", ueVersionString, (short)ueId), + UResource.fromId((short)uResourceId)); + } + + } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 5267ded1..50e85dd3 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -3,6 +3,7 @@ import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.factory.UriFactory; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; @@ -19,6 +20,10 @@ public abstract class UriValidator { */ public static UStatus validate(UUri uri) { final UAuthority uAuthority = uri.uAuthority(); + if (uri.isEmpty()) { + return UStatus.failed("Uri is empty.", Code.INVALID_ARGUMENT); + } + if (uAuthority.isMarkedRemote()) { if (uAuthority.device().isEmpty()) { return UStatus.failed("Uri is configured to be remote and is missing uAuthority device name.", Code.INVALID_ARGUMENT); @@ -66,4 +71,10 @@ public static UStatus validateRpcResponse(UUri uri) { return UStatus.ok(); } + + + public static UStatus validateLongUUri(String uri) { + final UUri uUri = UriFactory.parseFromUri(uri); + return validate(uUri); + } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index cb2bf852..627e912c 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -27,6 +27,11 @@ import static org.junit.jupiter.api.Assertions.*; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Objects; + class UAuthorityTest { @Test @@ -40,12 +45,12 @@ public void testHashCodeEquals() { public void testToString() { UAuthority uAuthority = UAuthority.remote("VCU", "my_VIN"); String sRemote = uAuthority.toString(); - String expectedRemote = "UAuthority{device='vcu', domain='my_vin', markedRemote=true}"; + String expectedRemote = "UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}"; assertEquals(expectedRemote, sRemote); UAuthority local = UAuthority.local(); String sLocal = local.toString(); - String expectedLocal = "UAuthority{device='null', domain='null', markedRemote=false}"; + String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=false}"; assertEquals(expectedLocal, sLocal); } @@ -55,12 +60,12 @@ public void testToString() { public void testToString_case_sensitivity() { UAuthority uAuthority = UAuthority.remote("vcU", "my_VIN"); String sRemote = uAuthority.toString(); - String expectedRemote = "UAuthority{device='vcu', domain='my_vin', markedRemote=true}"; + String expectedRemote = "UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}"; assertEquals(expectedRemote, sRemote); UAuthority local = UAuthority.local(); String sLocal = local.toString(); - String expectedLocal = "UAuthority{device='null', domain='null', markedRemote=false}"; + String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=false}"; assertEquals(expectedLocal, sLocal); } @@ -144,4 +149,45 @@ public void test_isRemote() { assertTrue(remote.isRemote()); assertTrue(remote.isMarkedRemote()); } + + + @Test + @DisplayName("Test creating uAuthority with invalid ip address") + public void test_create_uAuthority_with_invalid_ip_address() { + UAuthority remote = UAuthority.remote((InetAddress)null); + String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=true}"; + assertEquals(expectedLocal, remote.toString()); + assertFalse(remote.address().isPresent()); + } + + + @Test + @DisplayName("Test creating uAuthority with valid ip address") + public void test_create_uAuthority_with_valid_ip_address() { + InetAddress address = Inet6Address.getLoopbackAddress(); + + UAuthority remote = UAuthority.remote(address); + String expectedLocal = "UAuthority{device='null', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; + InetAddress address2 = remote.address().get(); + assertTrue(remote.address().isPresent()); + assertEquals(address, address2); + assertEquals(expectedLocal, remote.toString()); + } + + @Test + @DisplayName("Test creating uAuthority with valid ipv6 address") + public void test_create_uAuthority_with_valid_ipv6_address() { + String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; + InetAddress address = null; + try { + address = InetAddress.getByName(ipv6Address); + } + catch (UnknownHostException e) { + e.printStackTrace(); + } + + UAuthority remote = UAuthority.remote(address); + String expectedLocal = "UAuthority{device='null', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; + assertEquals(expectedLocal, remote.toString()); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 116d2b8a..f52940e1 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -44,11 +44,11 @@ public void testToString() { assertTrue(use.version().isPresent()); assertEquals("1", use.version().get()); - String expected = "UEntity{name='body.access', version='1'}"; + String expected = "UEntity{name='body.access', version='1', id='unknown'}"; assertEquals(expected, use.toString()); UEntity use1 = UEntity.fromName("body.access"); - assertEquals("UEntity{name='body.access', version='latest'}", use1.toString()); + assertEquals("UEntity{name='body.access', version='latest', id='unknown'}", use1.toString()); } @Test @@ -110,4 +110,28 @@ public void test_is_empty() { UEntity use4 = new UEntity("petapp", null); assertFalse(use4.isEmpty()); } + + @Test + @DisplayName("Test creating UEntity with id") + public void test_create_use_with_id() { + UEntity use = new UEntity("body.access", "1", (short)0); + assertEquals("body.access", use.name()); + assertTrue(use.version().isPresent()); + assertEquals("1", use.version().get()); + assertTrue(use.id().isPresent()); + assertEquals((int)0, (int)use.id().get()); + assertEquals("UEntity{name='body.access', version='1', id='0'}", use.toString()); + } + + @Test + @DisplayName("Test creating UEntity with invalid id") + public void test_create_use_with_invalid_id() { + UEntity use = new UEntity("body.access", "1", null); + assertEquals("body.access", use.name()); + assertTrue(use.version().isPresent()); + assertEquals("1", use.version().get()); + assertFalse(use.id().isPresent()); + assertEquals("UEntity{name='body.access', version='1', id='unknown'}", use.toString()); + } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 1387a86b..80e4cadb 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -39,7 +39,7 @@ public void testHashCodeEquals() { @DisplayName("Make sure the toString works") public void testToString() { UResource uResource = new UResource("door", "front_left", "Door"); - String expected = "UResource{name='door', instance='front_left', message='Door'}"; + String expected = "UResource{name='door', instance='front_left', message='Door', id='unknown'}"; assertEquals(expected, uResource.toString()); } @@ -184,4 +184,80 @@ public void test_create_rpc_response_using_response_method() { assertTrue(uResource.message().isEmpty()); } + @Test + @DisplayName("Test creating an UResource with valid id") + public void test_create_UResource_with_valid_id() { + UResource uResource = new UResource("door", "front_left", "Door", (short)5); + assertEquals("door", uResource.name()); + assertTrue(uResource.instance().isPresent()); + assertEquals("front_left", uResource.instance().get()); + assertTrue(uResource.message().isPresent()); + assertEquals("Door", uResource.message().get()); + assertTrue(uResource.id().isPresent()); + assertEquals((int)5, (int)uResource.id().get()); + assertEquals("UResource{name='door', instance='front_left', message='Door', id='5'}", uResource.toString()); + } + + @Test + @DisplayName("Test creating an UResource with invalid id") + public void test_create_UResource_with_invalid_id() { + UResource uResource = new UResource("door", "front_left", "Door", null); + assertEquals("door", uResource.name()); + assertTrue(uResource.instance().isPresent()); + assertEquals("front_left", uResource.instance().get()); + assertTrue(uResource.message().isPresent()); + assertEquals("Door", uResource.message().get()); + assertFalse(uResource.id().isPresent()); + assertEquals("UResource{name='door', instance='front_left', message='Door', id='unknown'}", uResource.toString()); + } + + @Test + @DisplayName("Test creating an UResource by calling fromId static method") + public void test_create_UResource_by_calling_fromId_static_method() { + UResource uResource = UResource.fromId((short)5); + assertEquals("unknown", uResource.name()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isPresent()); + assertEquals((int)5, (int)uResource.id().get()); + assertEquals("UResource{name='unknown', instance='null', message='null', id='5'}", uResource.toString()); + } + + @Test + @DisplayName("Test creating a response UResource by calling fromId") + public void test_create_response_UResource_by_calling_fromId() { + UResource uResource = UResource.fromId((short)0); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isPresent()); + assertEquals("response", uResource.instance().get()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isPresent()); + assertEquals((int)0, (int)uResource.id().get()); + assertEquals("UResource{name='rpc', instance='response', message='null', id='0'}", uResource.toString()); + } + + @Test + @DisplayName("Test creating a response UResource passing name, instance, and id") + public void test_create_response_UResource_passing_name_instance_and_id() { + UResource uResource = new UResource("rpc", "response", null, (short)0); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isPresent()); + assertEquals("response", uResource.instance().get()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isPresent()); + assertEquals((int)0, (int)uResource.id().get()); + assertEquals("UResource{name='rpc', instance='response', message='null', id='0'}", uResource.toString()); + } + + @Test + @DisplayName("Test creating a request UResource passing name, instance, and id") + public void test_create_request_UResource_passing_name_instance_and_id() { + UResource uResource = new UResource("rpc", null, null, (short)0); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isPresent()); + assertEquals((int)0, (int)uResource.id().get()); + assertEquals("UResource{name='rpc', instance='null', message='null', id='0'}", uResource.toString()); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 86ad78af..ff6ca889 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -28,6 +28,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Optional; + class UriTest { @Test @@ -46,21 +48,21 @@ public void testToString() { UUri uri = new UUri(uAuthorityLocal, use, uResource); - String expected = "Uri{uAuthority=UAuthority{device='null', domain='null', markedRemote=false}, " + - "uEntity=UEntity{name='body.access', version='1'}, " + - "uResource=UResource{name='door', instance='front_left', message='null'}}"; + String expected = "Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + + "uEntity=UEntity{name='body.access', version='1', id='unknown'}, " + + "uResource=UResource{name='door', instance='front_left', message='null', id='unknown'}}"; assertEquals(expected, uri.toString()); UUri uriRemote = new UUri(uAuthorityRemote, use, uResource); - String expectedRemote = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', markedRemote=true}, " + - "uEntity=UEntity{name='body.access', version='1'}, " + - "uResource=UResource{name='door', instance='front_left', message='null'}}"; + String expectedRemote = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + + "uEntity=UEntity{name='body.access', version='1', id='unknown'}, " + + "uResource=UResource{name='door', instance='front_left', message='null', id='unknown'}}"; assertEquals(expectedRemote, uriRemote.toString()); UUri uri2 = new UUri(uAuthorityRemote, use, UResource.empty()); - String expectedUri2 = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', markedRemote=true}, " + - "uEntity=UEntity{name='body.access', version='1'}, " + - "uResource=UResource{name='', instance='null', message='null'}}"; + String expectedUri2 = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + + "uEntity=UEntity{name='body.access', version='1', id='unknown'}, " + + "uResource=UResource{name='', instance='null', message='null', id='unknown'}}"; assertEquals(expectedUri2, uri2.toString()); } @@ -176,4 +178,18 @@ public void test_lazy_initialization_of_uprotocol_routing_string() { assertEquals("//vcu.my_vin/body.access/1/door.front_left", uri.uProtocolUri()); } + @Test + @DisplayName("Test getting and setting id") + public void test_getting_and_setting_id() { + UAuthority uAuthorityRemote = UAuthority.remote("VCU", "MY_VIN"); + UEntity use = new UEntity("body.access", "1"); + UResource uResource = UResource.fromNameWithInstance("door", "front_left"); + UUri uri = new UUri(uAuthorityRemote, use, uResource); + + assertTrue(uri.id(null).isEmpty()); + uri.id(1); + assertTrue(uri.id(null).isPresent()); + assertEquals(1, uri.id(null).get()); + } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java index 4fef2cac..d4e15aa9 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java @@ -30,6 +30,10 @@ import static org.junit.jupiter.api.Assertions.*; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + class UriFactoryTest { @Test @@ -969,4 +973,196 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { assertEquals("Door", Uri.uResource().message().get()); assertEquals(uri2, Uri.uProtocolUri()); } + + @Test + @DisplayName("Test Create a uProtocol Short URI from a URI Object") + public void test_build_short_uri_from_uri() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("body.access", "1", (short)5); + UResource uResource = new UResource("door", "front_left", "Door", (short)3); + + UUri Uri = new UUri(uAuthority, use, uResource); + String uProtocolUri = UriFactory.buildUProtocolShortUri(Uri); + assertEquals("/5/1/3", uProtocolUri); + } + + @Test + @DisplayName("Test Create a uProtocol Short URI for empty URI") + public void test_build_short_uri_from_uri_missing_ids() { + UUri Uri = UUri.empty(); + String uProtocolUri = UriFactory.buildUProtocolShortUri(Uri); + assertEquals("", uProtocolUri); + } + + @Test + @DisplayName("Test Create a uProtocol Short URI for null URI") + public void test_build_short_uri_from_null_uri() { + String uProtocolUri = UriFactory.buildUProtocolShortUri(null); + assertEquals("", uProtocolUri); + } + + + @Test + @DisplayName("Test Create a uProtocol Short URI with remote URI") + public void test_build_short_uri_from_remote_uri() { + String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; + InetAddress address = null; + try { + address = InetAddress.getByName(ipv6Address); + } + catch (UnknownHostException e) { + e.printStackTrace(); + } + UAuthority uAuthority = UAuthority.remote(address); + UEntity use = new UEntity("body.access", "1", (short)5); + UResource uResource = new UResource("door", "front_left", "Door", (short)3); + + String uProtocolUri = UriFactory.buildUProtocolShortUri(uAuthority, use, uResource); + assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/5/1/3", uProtocolUri); + } + + @Test + @DisplayName("Test Create a uProtocol Short URI with remote URI without uEntity") + public void test_build_short_uri_from_remote_uri_missing_uentity() { + String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; + InetAddress address = null; + try { + address = InetAddress.getByName(ipv6Address); + } + catch (UnknownHostException e) { + e.printStackTrace(); + } + UAuthority uAuthority = UAuthority.remote(address); + + String uProtocolUri = UriFactory.buildUProtocolShortUri(uAuthority, UEntity.empty(), UResource.empty()); + assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/", uProtocolUri); + } + + @Test + @DisplayName("Test Create a uProtocol Short URI when address is missing") + public void test_build_short_uri_from_remote_uri_missing_address() { + UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); + UEntity use = new UEntity("body.access", "1"); + UResource uResource = UResource.fromName("door"); + String ucustomUri = UriFactory.buildUProtocolShortUri(uAuthority, use, uResource); + assertEquals("///", ucustomUri); + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI with empty URI") + public void test_build_micro_uri_from_uri_missing_ids() { + UUri Uri = UUri.empty(); + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(Uri); + assertEquals(0, uProtocolUri.length); + } + + + @Test + @DisplayName("Test Create a uProtocol Micro URI with remote URI without uEntity") + public void test_build_micro_uri_from_remote_uri_missing_uentity() { + String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; + InetAddress address = null; + try { + address = InetAddress.getByName(ipv6Address); + } + catch (UnknownHostException e) { + e.printStackTrace(); + } + UAuthority uAuthority = UAuthority.remote(address); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, UEntity.empty(), UResource.empty())); + assertEquals(0, uProtocolUri.length); + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI for local UAuthority") + public void test_build_micro_uri_from_local_uri_simple_version() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("body.access", "1", (short)5); + UResource uResource = new UResource("door", "front_left", "Door", (short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + assertEquals(8, uProtocolUri.length); + assertEquals(1, uProtocolUri[0]); // version 1 + assertEquals(0, uProtocolUri[1]); // local + assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) + assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) + assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) + assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) + assertEquals(1<<3, uProtocolUri[6]); // UEntity Version (MSB) + assertEquals(0, uProtocolUri[7]); // UEntity Version (LSB) + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI for local UAuthority") + public void test_build_micro_uri_from_local_uri() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("body.access", "1.1", (short)5); + UResource uResource = new UResource("door", "front_left", "Door", (short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + assertEquals(8, uProtocolUri.length); + assertEquals(1, uProtocolUri[0]); // version 1 + assertEquals(0, uProtocolUri[1]); // local + assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) + assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) + assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) + assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) + assertEquals(1<<3, uProtocolUri[6]); // UEntity Version (MSB) + assertEquals(1, uProtocolUri[7]); // UEntity Version (LSB) + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI for local UAuthority large minor version") + public void test_build_micro_uri_from_local_uri_large_minor_version() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("body.access", "1.599", (short)5); + UResource uResource = new UResource("door", "front_left", "Door", (short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + assertEquals(8, uProtocolUri.length); + assertEquals(1, uProtocolUri[0]); // version 1 + assertEquals(0, uProtocolUri[1]); // local + assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) + assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) + assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) + assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) + assertEquals(10, uProtocolUri[6]); // UEntity Version (MSB) + assertEquals(599 & 0xff, uProtocolUri[7]); // UEntity Version (LSB) + } + + + @Test + @DisplayName("Test Create a uProtocol Micro URI for local UAuthority no version") + public void test_build_micro_uri_from_local_uri_no_version() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("body.access", null, (short)5); + UResource uResource = new UResource("door", "front_left", "Door", (short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + assertEquals(8, uProtocolUri.length); + assertEquals(1, uProtocolUri[0]); // version 1 + assertEquals(0, uProtocolUri[1]); // local + assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) + assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) + assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) + assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) + assertEquals((byte)Short.MAX_VALUE>>8, uProtocolUri[6]); // UEntity Version (MSB) + assertEquals((byte)Short.MAX_VALUE, uProtocolUri[7]); // UEntity Version (LSB) + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI to byte[] then call parseFromMicroUri to convert back to UUri") + public void test_build_micro_uri_from_local_uri_then_parse_back_to_uri() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("", "1.599", (short)5); + UResource uResource = UResource.fromId((short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); + assertEquals(uAuthority, Uri.uAuthority()); + assertEquals(use, Uri.uEntity()); + assertEquals(uResource, Uri.uResource()); + } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index c9d5134c..dce5b6aa 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -41,7 +41,7 @@ public void test_validate_blank_uri() { final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @@ -51,7 +51,7 @@ public void test_validate_uri_with_no_entity_name() { final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is configured to be remote and is missing uAuthority device name.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @@ -69,7 +69,7 @@ public void test_validate_with_malformed_uri() { final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @@ -96,7 +96,7 @@ public void test_validateRpcMethod_with_malformed_uri() { final UStatus status = UriValidator.validateRpcMethod(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @@ -114,7 +114,7 @@ public void test_validateRpcResponse_with_malformed_uri() { final UStatus status = UriValidator.validateRpcResponse(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index a2aed034..b802c4b4 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -209,7 +209,7 @@ public void test_validating_invalid_sink_attribute() { assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Uri is configured to be remote and is missing uAuthority device name."); + assertEquals(status.msg(), "Uri is empty."); } @Test From fa95280fb4539a620f0c2223fb69565f77ee305c Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Mon, 4 Sep 2023 14:22:03 +0300 Subject: [PATCH 10/52] working on UPayload --- .../utransport/datamodel/UPayload.java | 24 +++--- .../utransport/datamodel/UPayloadTest.java | 76 +++++++++++++++++++ 2 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java index 1726ea1c..fb6ae633 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java @@ -24,7 +24,7 @@ import java.util.Arrays; /** - * The UPayload contains the clean Payload information at its raw serialized structure of a byte[] + * The UPayload contains the clean Payload information along with its raw serialized structure of a byte[]. */ public class UPayload { @@ -36,18 +36,17 @@ public class UPayload { /** * Create a UPayload. * @param data A byte array of the actual data. - * @param representationHint Hint regarding what the bytes represent such as simple binary, a String or maybe a special type of String. */ public UPayload(byte[] data) { this.data = data; } /** - * The actual serialized or raw data, which can be deserialized or simply used as is using the hint. - * @return Returns the actual serialized or raw data, which can be deserialized or simply used as is using the hint. + * The actual serialized or raw data, which can be deserialized or simply used as is. + * @return Returns the actual serialized or raw data, which can be deserialized or simply used as is. */ public byte[] data() { - return this.data; + return this.data == null ? EMPTY.data() : this.data; } @@ -58,6 +57,15 @@ public static UPayload empty() { return EMPTY; } + /** + * Static factory method for creating the payload from a simple String. + * @param payload String payload. + * @return Returns a UPayload from the string argument. + */ + public static UPayload fromString(String payload) { + return new UPayload(payload.getBytes()); + } + /** * @return Returns true if the data in the UPayload is empty. */ @@ -76,14 +84,12 @@ public boolean equals(Object o) { @Override public int hashCode() { - int result = Arrays.hashCode(data); - return result; + return Arrays.hashCode(data); } @Override public String toString() { return "UPayload{" + - "data=" + Arrays.toString(data) + - '}'; + "data=" + Arrays.toString(data()) + " size=" + data().length + '}'; } } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java new file mode 100644 index 00000000..cad85959 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java @@ -0,0 +1,76 @@ +package org.eclipse.uprotocol.utransport.datamodel; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.*; + +class UPayloadTest { + + @Test + @DisplayName("Make sure the equals and hash code works") + public void testHashCodeEquals() { + EqualsVerifier.forClass(UPayload.class).usingGetClass().verify(); + } + + @Test + @DisplayName("Make sure the toString works on empty") + public void testToString_with_empty() { + UPayload uPayload = UPayload.empty(); + assertEquals("UPayload{data=[] size=0}", uPayload.toString()); + } + + @Test + @DisplayName("Make sure the toString works on null") + public void testToString_with_null() { + UPayload uPayload = new UPayload(null); + assertEquals("UPayload{data=[] size=0}", uPayload.toString()); + } + + @Test + @DisplayName("Make sure the toString works") + public void testToString() { + UPayload uPayload = UPayload.fromString("hello"); + assertEquals("UPayload{data=[104, 101, 108, 108, 111] size=5}", uPayload.toString()); + } + + @Test + @DisplayName("Create an empty UPyload") + public void create_an_empty_upayload() { + UPayload uPayload = UPayload.empty(); + assertEquals(0, uPayload.data().length); + assertTrue(uPayload.isEmpty()); + } + + @Test + @DisplayName("Create a UPyload with null") + public void create_upayload_with_null() { + UPayload uPayload = new UPayload(null); + assertEquals(0, uPayload.data().length); + assertTrue(uPayload.isEmpty()); + } + + @Test + @DisplayName("Create a UPayload from some bytes") + public void create_upayload_from_bytes() { + String stringData = "hello"; + UPayload uPayload = new UPayload(stringData.getBytes(StandardCharsets.UTF_8)); + assertEquals(stringData.length(), uPayload.data().length); + assertFalse(uPayload.isEmpty()); + assertEquals(stringData, new String(uPayload.data())); + } + + @Test + @DisplayName("Create a UPayload from a string") + public void create_upayload_from_a_string() { + String stringData = "hello world"; + UPayload uPayload = UPayload.fromString(stringData); + assertEquals(stringData.length(), uPayload.data().length); + assertFalse(uPayload.isEmpty()); + assertEquals(stringData, new String(uPayload.data())); + } + +} \ No newline at end of file From 15a719b25031a663e4971b4b429fe40fb1548cf0 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 5 Sep 2023 20:17:21 -0400 Subject: [PATCH 11/52] More tests for URI validation --- .../uprotocol/uri/datamodel/UAuthority.java | 2 +- .../uprotocol/uri/validator/UriValidator.java | 9 +------- .../uprotocol/uri/factory/UriFactoryTest.java | 1 + .../uri/validator/UriValidatorTest.java | 22 +++++++++++++++++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 2ec2a928..5048be53 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -133,7 +133,7 @@ public static UAuthority empty() { * @return returns true if this authority is remote, meaning it contains a device or a domain. */ public boolean isRemote() { - return domain().isPresent() || device().isPresent(); + return address().isPresent() || domain().isPresent() || device().isPresent(); } /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 50e85dd3..82b656d1 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -1,6 +1,5 @@ package org.eclipse.uprotocol.uri.validator; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.factory.UriFactory; @@ -11,7 +10,7 @@ /** * class for validating Uris. */ -public abstract class UriValidator { +public interface UriValidator { /** * Validate a Uri to ensure that it has at least a name for the uEntity. @@ -19,16 +18,10 @@ public abstract class UriValidator { * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validate(UUri uri) { - final UAuthority uAuthority = uri.uAuthority(); if (uri.isEmpty()) { return UStatus.failed("Uri is empty.", Code.INVALID_ARGUMENT); } - if (uAuthority.isMarkedRemote()) { - if (uAuthority.device().isEmpty()) { - return UStatus.failed("Uri is configured to be remote and is missing uAuthority device name.", Code.INVALID_ARGUMENT); - } - } if (uri.uEntity().name().isBlank()) { return UStatus.failed("Uri is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java index d4e15aa9..32b0dfc1 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java @@ -1164,5 +1164,6 @@ public void test_build_micro_uri_from_local_uri_then_parse_back_to_uri() { assertEquals(use, Uri.uEntity()); assertEquals(uResource, Uri.uResource()); } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index dce5b6aa..cb70eaf7 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -27,6 +27,9 @@ import static org.junit.jupiter.api.Assertions.*; +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.factory.UriFactory; import org.eclipse.uprotocol.utransport.datamodel.UStatus; @@ -71,6 +74,17 @@ public void test_validate_with_malformed_uri() { assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Uri is empty.", status.msg()); } + + + @Test + @DisplayName("Test validate with blank UEntity Name") + public void test_validate_with_blank_uentity_name_uri() { + final UUri uri = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpc("echo")); + final UStatus status = UriValidator.validate(uri); + assertFalse(uri.isEmpty()); + assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + } @Test @DisplayName("Test validateRpcMethod with valid URI") @@ -134,4 +148,12 @@ public void test_validateRpcResponse_with_invalid_rpc_response_type() { assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); } + + @Test + @DisplayName("Test validateLongUUri with valid URI") + public void test_validateLongUUri_with_valid_uri() { + final UUri uri = UriFactory.parseFromUri("/hartley//rpc.echo"); + final UStatus status = UriValidator.validateLongUUri(uri.uProtocolUri()); + assertEquals(UStatus.ok(), status); + } } From 81949c60a29f2dd18c25169e48937ee7ee7546ec Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 6 Sep 2023 14:27:18 -0400 Subject: [PATCH 12/52] Moved SerializationHint into UPayload --- .../utransport/datamodel/UAttributes.java | 29 +++---------------- .../utransport/datamodel/UPayload.java | 29 ++++++++++++++----- .../utransport/datamodel/UPayloadTest.java | 28 +++++++++++++----- .../validator/UAttributesValidatorTest.java | 6 ++-- 4 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 129b6930..0c87f9ca 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -28,7 +28,7 @@ public class UAttributes { - private static final UAttributes EMPTY = new UAttributes(null, null, null, null, null, null, null, null, null, null); + private static final UAttributes EMPTY = new UAttributes(null, null, null, null, null, null, null, null, null); // Required Attributes private final UUID id; // Unique identifier for the message @@ -38,7 +38,6 @@ public class UAttributes { // Optional Attributes private final Integer ttl; // Time to live in milliseconds private final String token; // Authorization token used for TAP - private final USerializationHint hint; // Hint regarding the bytes contained within the UPayload private final UUri sink; // Explicit destination URI private final Integer plevel; // Permission Level private final Integer commstatus; // Communication Status @@ -61,13 +60,12 @@ public class UAttributes { * @return Returns a constructed UAttributes. */ private UAttributes(UUID id, UMessageType type, UPriority priority, Integer ttl, String token, - USerializationHint hint, UUri sink, Integer plevel, Integer commstatus, UUID reqid) { + UUri sink, Integer plevel, Integer commstatus, UUID reqid) { this.id = id; this.type = type; this.priority = priority; this.ttl = ttl; this.token = token; - this.hint = hint; this.sink = sink; this.plevel = plevel; this.commstatus = commstatus; @@ -75,7 +73,7 @@ private UAttributes(UUID id, UMessageType type, UPriority priority, Integer ttl, } private UAttributes(UAttributesBuilder builder) { - this(builder.id, builder.type, builder.priority, builder.ttl, builder.token, builder.hint, builder.sink, + this(builder.id, builder.type, builder.priority, builder.ttl, builder.token, builder.sink, builder.plevel, builder.commstatus, builder.reqid); } @@ -90,7 +88,7 @@ public static UAttributes empty() { public boolean isEmpty() { return this.id == null && this.type == null && this.priority == null && this.ttl == null && this.token == null - && this.hint == null && this.sink == null && this.plevel == null && this.commstatus == null + && this.sink == null && this.plevel == null && this.commstatus == null && this.reqid == null; } @@ -134,14 +132,6 @@ public Optional token() { return token == null || token.isBlank() ? Optional.empty() : Optional.of(token); } - /** - * How long this event should live for after it was generated (in milliseconds). - * Events without this attribute (or value is 0) MUST NOT timeout. - * @return Returns an Optional time to live attribute. - */ - public Optional serializationHint() { - return hint == null ? Optional.empty() : Optional.of(this.hint); - } /** * an explicit destination URI. @@ -186,7 +176,6 @@ public static class UAttributesBuilder { private UPriority priority; private Integer ttl; private String token; - private USerializationHint hint; private UUri sink; private Integer plevel; private Integer commstatus; @@ -244,16 +233,6 @@ public UAttributesBuilder withToken(String token) { return this; } - /** - * Add the hint regarding the bytes contained within the UPayload. - * @param hint the hint regarding the bytes contained within the UPayload. - * @return Returns the UAttributesBuilder with the configured hint. - */ - public UAttributesBuilder withHint(USerializationHint hint) { - this.hint = hint; - return this; - } - /** * Add the explicit destination URI. * @param sink the explicit destination URI. diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java index fb6ae633..8a1681ad 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java @@ -22,23 +22,29 @@ package org.eclipse.uprotocol.utransport.datamodel; import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; /** * The UPayload contains the clean Payload information along with its raw serialized structure of a byte[]. */ public class UPayload { - private static final UPayload EMPTY = new UPayload(new byte[0]); + private static final UPayload EMPTY = new UPayload(new byte[0], null); private final byte[] data; + private final USerializationHint hint; // Hint regarding the bytes contained within the UPayload + /** * Create a UPayload. * @param data A byte array of the actual data. */ - public UPayload(byte[] data) { + public UPayload(byte[] data, USerializationHint hint) { + this.hint = hint; this.data = data; + } /** @@ -49,6 +55,13 @@ public byte[] data() { return this.data == null ? EMPTY.data() : this.data; } + /** + * The hint regarding the bytes contained within the UPayload. + * @return Returns the hint regarding the bytes contained within the UPayload. + */ + public Optional hint() { + return (hint == null) ? Optional.empty() : Optional.of(hint); + } /** * @return Returns an empty representation of UPayload. @@ -60,10 +73,11 @@ public static UPayload empty() { /** * Static factory method for creating the payload from a simple String. * @param payload String payload. + * @param hint Optional hint regarding the bytes contained within the UPayload. * @return Returns a UPayload from the string argument. */ - public static UPayload fromString(String payload) { - return new UPayload(payload.getBytes()); + public static UPayload fromString(String payload, USerializationHint hint) { + return new UPayload(payload.getBytes(), hint); } /** @@ -79,17 +93,18 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UPayload uPayload = (UPayload) o; - return Arrays.equals(data, uPayload.data); + return Arrays.equals(data, uPayload.data) && this.hint == uPayload.hint; } @Override public int hashCode() { - return Arrays.hashCode(data); + return Objects.hash(Arrays.hashCode(data),hint); } @Override public String toString() { return "UPayload{" + - "data=" + Arrays.toString(data()) + " size=" + data().length + '}'; + "data=" + Arrays.toString(data()) + " size=" + data().length + + ", hint=" + hint +'}'; } } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java index cad85959..856a08e4 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java @@ -20,21 +20,21 @@ public void testHashCodeEquals() { @DisplayName("Make sure the toString works on empty") public void testToString_with_empty() { UPayload uPayload = UPayload.empty(); - assertEquals("UPayload{data=[] size=0}", uPayload.toString()); + assertEquals("UPayload{data=[] size=0, hint=null}", uPayload.toString()); } @Test @DisplayName("Make sure the toString works on null") public void testToString_with_null() { - UPayload uPayload = new UPayload(null); - assertEquals("UPayload{data=[] size=0}", uPayload.toString()); + UPayload uPayload = new UPayload(null, null); + assertEquals("UPayload{data=[] size=0, hint=null}", uPayload.toString()); } @Test @DisplayName("Make sure the toString works") public void testToString() { - UPayload uPayload = UPayload.fromString("hello"); - assertEquals("UPayload{data=[104, 101, 108, 108, 111] size=5}", uPayload.toString()); + UPayload uPayload = UPayload.fromString("hello", null); + assertEquals("UPayload{data=[104, 101, 108, 108, 111] size=5, hint=null}", uPayload.toString()); } @Test @@ -48,7 +48,7 @@ public void create_an_empty_upayload() { @Test @DisplayName("Create a UPyload with null") public void create_upayload_with_null() { - UPayload uPayload = new UPayload(null); + UPayload uPayload = new UPayload(null, null); assertEquals(0, uPayload.data().length); assertTrue(uPayload.isEmpty()); } @@ -57,7 +57,7 @@ public void create_upayload_with_null() { @DisplayName("Create a UPayload from some bytes") public void create_upayload_from_bytes() { String stringData = "hello"; - UPayload uPayload = new UPayload(stringData.getBytes(StandardCharsets.UTF_8)); + UPayload uPayload = new UPayload(stringData.getBytes(StandardCharsets.UTF_8), null); assertEquals(stringData.length(), uPayload.data().length); assertFalse(uPayload.isEmpty()); assertEquals(stringData, new String(uPayload.data())); @@ -67,10 +67,22 @@ public void create_upayload_from_bytes() { @DisplayName("Create a UPayload from a string") public void create_upayload_from_a_string() { String stringData = "hello world"; - UPayload uPayload = UPayload.fromString(stringData); + UPayload uPayload = UPayload.fromString(stringData, null); assertEquals(stringData.length(), uPayload.data().length); assertFalse(uPayload.isEmpty()); assertEquals(stringData, new String(uPayload.data())); + assertFalse(uPayload.hint().isPresent()); + } + + @Test + @DisplayName("Create a UPayload from a string with a hint") + public void create_upayload_from_a_string_with_a_hint() { + String stringData = "hello world"; + UPayload uPayload = UPayload.fromString(stringData, USerializationHint.JSON); + assertEquals(stringData.length(), uPayload.data().length); + assertFalse(uPayload.isEmpty()); + assertEquals(stringData, new String(uPayload.data())); + assertEquals(USerializationHint.JSON, uPayload.hint().get()); } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index b802c4b4..1480deab 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -32,7 +32,6 @@ import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; import org.eclipse.uprotocol.utransport.datamodel.UPriority; -import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; @@ -431,13 +430,12 @@ public void test_validating_response_validator_with_wrong_messagetype() { @Test - @DisplayName("test validating request containing hint and token") - public void test_validating_request_containing_hint_and_token() { + @DisplayName("test validating request containing token") + public void test_validating_request_containing_token() { final UAttributes attributes = new UAttributesBuilder() .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .withPriority(UPriority.LOW) .withType(UMessageType.PUBLISH) - .withHint(USerializationHint.JSON) .withToken("null") .build(); From 2928e93ec1cb852be080ebc56effd04defe92c3e Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Wed, 6 Sep 2023 22:33:55 +0300 Subject: [PATCH 13/52] working on UStatus --- pom.xml | 3 +- .../utransport/datamodel/UStatus.java | 106 ++++++------ .../utransport/datamodel/UStatusTest.java | 162 ++++++++++++++++++ 3 files changed, 213 insertions(+), 58 deletions(-) create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java diff --git a/pom.xml b/pom.xml index e0152045..40d1f7ab 100644 --- a/pom.xml +++ b/pom.xml @@ -153,7 +153,7 @@ nl.jqno.equalsverifier equalsverifier - 3.10.1 + 3.14.1 test @@ -173,6 +173,7 @@ nl.jqno.equalsverifier equalsverifier + 3.14.1 test diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java index 75388bcb..3347f826 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java @@ -4,10 +4,10 @@ import java.util.Objects; import java.util.Optional; - /** - * UProtocol general Ack requestRpcMessage for all operations. - * Can be made into a Monad in the future. + * UProtocol general status for all operations. + * A UStatus is generated using the static factory methods, making is easy to quickly create UStatus objects. + * Example: UStatus ok = UStatus.ok(); */ public abstract class UStatus { @@ -16,39 +16,37 @@ public abstract class UStatus { public abstract boolean isSuccess(); public abstract String msg(); - public abstract int getCode(); /** - * Enum to contain the status code that we map to google.rpc.Code - * - * Please refer to https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto + * Enum to contain the status code that we map to google.rpc.Code. + * Please refer to code.proto * for documentation on the codes listed below - * + * */ public enum Code { - OK(com.google.rpc.Code.OK_VALUE), - CANCELLED(com.google.rpc.Code.CANCELLED_VALUE), - UNKNOWN(com.google.rpc.Code.UNKNOWN_VALUE), - INVALID_ARGUMENT(com.google.rpc.Code.INVALID_ARGUMENT_VALUE), - DEADLINE_EXCEEDED(com.google.rpc.Code.DEADLINE_EXCEEDED_VALUE), - NOT_FOUND(com.google.rpc.Code.NOT_FOUND_VALUE), - ALREADY_EXISTS(com.google.rpc.Code.ALREADY_EXISTS_VALUE), - PERMISSION_DENIED(com.google.rpc.Code.PERMISSION_DENIED_VALUE), - UNAUTHENTICATED(com.google.rpc.Code.UNAUTHENTICATED_VALUE), - RESOURCE_EXHAUSTED(com.google.rpc.Code.RESOURCE_EXHAUSTED_VALUE), - FAILED_PRECONDITION(com.google.rpc.Code.FAILED_PRECONDITION_VALUE), - ABORTED(com.google.rpc.Code.ABORTED_VALUE), - OUT_OF_RANGE(com.google.rpc.Code.OUT_OF_RANGE_VALUE), - UNIMPLEMENTED(com.google.rpc.Code.UNIMPLEMENTED_VALUE), - INTERNAL(com.google.rpc.Code.INTERNAL_VALUE), - UNAVAILABLE(com.google.rpc.Code.UNAVAILABLE_VALUE), - DATA_LOSS(com.google.rpc.Code.DATA_LOSS_VALUE), - UNSPECIFIED(-1); - - private int value; - private Code(int value) { + OK (com.google.rpc.Code.OK_VALUE), + CANCELLED (com.google.rpc.Code.CANCELLED_VALUE), + UNKNOWN (com.google.rpc.Code.UNKNOWN_VALUE), + INVALID_ARGUMENT (com.google.rpc.Code.INVALID_ARGUMENT_VALUE), + DEADLINE_EXCEEDED (com.google.rpc.Code.DEADLINE_EXCEEDED_VALUE), + NOT_FOUND (com.google.rpc.Code.NOT_FOUND_VALUE), + ALREADY_EXISTS (com.google.rpc.Code.ALREADY_EXISTS_VALUE), + PERMISSION_DENIED (com.google.rpc.Code.PERMISSION_DENIED_VALUE), + UNAUTHENTICATED (com.google.rpc.Code.UNAUTHENTICATED_VALUE), + RESOURCE_EXHAUSTED (com.google.rpc.Code.RESOURCE_EXHAUSTED_VALUE), + FAILED_PRECONDITION (com.google.rpc.Code.FAILED_PRECONDITION_VALUE), + ABORTED (com.google.rpc.Code.ABORTED_VALUE), + OUT_OF_RANGE (com.google.rpc.Code.OUT_OF_RANGE_VALUE), + UNIMPLEMENTED (com.google.rpc.Code.UNIMPLEMENTED_VALUE), + INTERNAL (com.google.rpc.Code.INTERNAL_VALUE), + UNAVAILABLE (com.google.rpc.Code.UNAVAILABLE_VALUE), + DATA_LOSS (com.google.rpc.Code.DATA_LOSS_VALUE), + UNSPECIFIED (-1); + + private final int value; + Code (int value) { this.value = value; } @@ -57,9 +55,9 @@ public int value() { } /** - * Get the Code from an integer value - * @param value The integer value of the Code - * @return Returns the Code if found, otherwise returns Optional.empty() + * Get the Code from an integer value. + * @param value The integer value of the Code. + * @return Returns the Code if found, otherwise returns Optional.empty(). */ public static Optional from(int value) { return Arrays.stream(Code.values()) @@ -69,12 +67,12 @@ public static Optional from(int value) { /** - * Get the Code from a google.rpc.Code - * @param code The google.rpc.Code - * @return Returns the Code if found, otherwise returns Optional.empty() + * Get the Code from a google.rpc.Code. + * @param code The google.rpc.Code. + * @return Returns the Code if found, otherwise returns Optional.empty(). */ public static Optional from(com.google.rpc.Code code) { - if ( (code == null) || (code == com.google.rpc.Code.UNRECOGNIZED) ) { + if (code == null || code == com.google.rpc.Code.UNRECOGNIZED) { return Optional.empty(); } return Arrays.stream(Code.values()) @@ -83,7 +81,6 @@ public static Optional from(com.google.rpc.Code code) { } } - /** * Return true if UStatus is a failure * @return Returns true if the UStatus is successful. @@ -92,15 +89,15 @@ public boolean isFailed() { return !isSuccess(); } - @Override public String toString() { - return String.format("UMessage %s %s %s", isSuccess() ? "ok" : "failed", - isSuccess() ? "id =" : "msg=", msg()); + return String.format("UStatus %s %s%s code=%s", isSuccess() ? "ok" : "failed", + isSuccess() ? "id=" : "msg=", msg(), + getCode()); } /** - * A successful UStatus + * A successful UStatus. */ private static class OKSTATUS extends UStatus { @@ -144,7 +141,7 @@ public int hashCode() { /** - * A failed UStatus + * A failed UStatus. */ private static class FAILSTATUS extends UStatus { @@ -160,14 +157,9 @@ private FAILSTATUS(String failMsg, Code code) { private FAILSTATUS(String failMsg, int value) { Optional code = Code.from(value); this.failMsg = failMsg; - if (code.isPresent()) { - this.code = code.get(); - } else { - this.code = Code.UNSPECIFIED; - } + this.code = code.orElse(Code.UNSPECIFIED); } - @Override public boolean isSuccess() { return false; @@ -178,23 +170,23 @@ public String msg() { return this.failMsg; } + @Override + public int getCode() { + return code.value; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - FAILSTATUS failstatus = (FAILSTATUS) o; - return code == failstatus.code && Objects.equals(failMsg, failstatus.failMsg); + FAILSTATUS that = (FAILSTATUS) o; + return Objects.equals(failMsg, that.failMsg) && code == that.code; } @Override public int hashCode() { return Objects.hash(failMsg, code); } - - @Override - public int getCode() { - return code.value; - } } @@ -207,11 +199,11 @@ public static UStatus ok(String ackId) { } public static UStatus failed() { - return new FAILSTATUS(FAILED, 0); + return new FAILSTATUS(FAILED, Code.UNKNOWN.value()); } public static UStatus failed(String msg) { - return new FAILSTATUS(msg, 0); + return new FAILSTATUS(msg, Code.UNKNOWN.value()); } public static UStatus failed(String msg, int failureReason) { diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java new file mode 100644 index 00000000..7db61427 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java @@ -0,0 +1,162 @@ +package org.eclipse.uprotocol.utransport.datamodel; + +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +class UStatusTest { + + @Test + @DisplayName("Make sure the equals and hash code works") + public void testHashCodeEquals() { + // can't test equals and hashcode for private classes - need to figure this out + EqualsVerifier.forClass(UStatus.class) + .suppress(Warning.INHERITED_DIRECTLY_FROM_OBJECT) + .usingGetClass().verify(); + } + + @Test + @DisplayName("Make sure the toString works on ok status") + public void testToString_for_ok_status() { + UStatus ok = UStatus.ok(); + assertEquals("UStatus ok id=ok code=0", ok.toString()); + } + + @Test + @DisplayName("Make sure the toString works on ok status with Id") + public void testToString_for_ok_status_with_id() { + UStatus ok = UStatus.ok("boo"); + assertEquals("UStatus ok id=boo code=0", ok.toString()); + } + + @Test + @DisplayName("Make sure the toString works on failed status") + public void testToString_for_failed_status() { + UStatus failed = UStatus.failed(); + assertEquals("UStatus failed msg=failed code=2", failed.toString()); + } + + @Test + @DisplayName("Make sure the toString works on failed status with message") + public void testToString_for_failed_status_with_message() { + UStatus failed = UStatus.failed("boom"); + assertEquals("UStatus failed msg=boom code=2", failed.toString()); + } + + @Test + @DisplayName("Make sure the toString works on failed status with message and failure reason") + public void testToString_for_failed_status_with_message_and_failure_reason() { + UStatus failed = UStatus.failed("boom", UStatus.Code.INVALID_ARGUMENT.value()); + assertEquals("UStatus failed msg=boom code=3", failed.toString()); + } + + @Test + @DisplayName("Make sure the toString works on failed status with message and Code") + public void testToString_for_failed_status_with_message_and_code() { + UStatus failed = UStatus.failed("boom", UStatus.Code.INVALID_ARGUMENT); + assertEquals("UStatus failed msg=boom code=3", failed.toString()); + } + + @Test + @DisplayName("Create ok status") + public void create_ok_status() { + UStatus ok = UStatus.ok(); + assertTrue(ok.isSuccess()); + assertFalse(ok.isFailed()); + assertEquals("ok", ok.msg()); + assertEquals(0, ok.getCode()); + } + + @Test + @DisplayName("Create ok status with Id") + public void create_ok_status_with_id() { + UStatus ok = UStatus.ok("boo"); + assertTrue(ok.isSuccess()); + assertFalse(ok.isFailed()); + assertEquals("boo", ok.msg()); + assertEquals(0, ok.getCode()); + } + + @Test + @DisplayName("Create failed status") + public void create_failed_status() { + UStatus failed = UStatus.failed(); + assertFalse(failed.isSuccess()); + assertTrue(failed.isFailed()); + assertEquals("failed", failed.msg()); + assertEquals(2, failed.getCode()); + } + + @Test + @DisplayName("Create failed status with message") + public void create_failed_status_with_message() { + UStatus failed = UStatus.failed("boom"); + assertFalse(failed.isSuccess()); + assertTrue(failed.isFailed()); + assertEquals("boom", failed.msg()); + assertEquals(2, failed.getCode()); + } + + @Test + @DisplayName("Create failed status with message and failure reason") + public void create_failed_status_with_message_and_failure_reason() { + UStatus failed = UStatus.failed("boom", UStatus.Code.INVALID_ARGUMENT.value()); + assertFalse(failed.isSuccess()); + assertTrue(failed.isFailed()); + assertEquals("boom", failed.msg()); + assertEquals(3, failed.getCode()); + } + + @Test + @DisplayName("Create failed status with message and Code") + public void create_failed_status_with_message_and_code() { + UStatus failed = UStatus.failed("boom", UStatus.Code.INVALID_ARGUMENT); + assertFalse(failed.isSuccess()); + assertTrue(failed.isFailed()); + assertEquals("boom", failed.msg()); + assertEquals(3, failed.getCode()); + } + + @Test + @DisplayName("Code from a known int code") + public void code_from_a_known_int_code() { + final Optional code = UStatus.Code.from(4); + assertTrue(code.isPresent()); + assertEquals("DEADLINE_EXCEEDED", code.get().name()); + } + + @Test + @DisplayName("Code from a unknown int code") + public void code_from_a_unknown_int_code() { + final Optional code = UStatus.Code.from(299); + assertTrue(code.isEmpty()); + } + + @Test + @DisplayName("Code from a known google code") + public void code_from_a_known_google_code() { + final Optional code = UStatus.Code.from(com.google.rpc.Code.INVALID_ARGUMENT); + assertTrue(code.isPresent()); + assertEquals("INVALID_ARGUMENT", code.get().name()); + } + + @Test + @DisplayName("Code from a null google code") + public void code_from_a_null_google_code() { + final Optional code = UStatus.Code.from(null); + assertTrue(code.isEmpty()); + } + + @Test + @DisplayName("Code from a UNRECOGNIZED google code") + public void code_from_a_UNRECOGNIZED_google_code() { + final Optional code = UStatus.Code.from(com.google.rpc.Code.UNRECOGNIZED); + assertTrue(code.isEmpty()); + } + +} \ No newline at end of file From 7279ddd186855ba4e03f9397557c3fc9ed32615e Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 6 Sep 2023 19:55:57 -0400 Subject: [PATCH 14/52] More micro URI factory tests --- .../uprotocol/uri/datamodel/UAuthority.java | 6 +- .../eclipse/uprotocol/uri/datamodel/UUri.java | 3 +- .../uprotocol/uri/factory/UriFactory.java | 96 +++++++-------- .../uprotocol/uri/factory/UriFactoryTest.java | 109 ++++++++++++++++-- 4 files changed, 157 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 5048be53..ac3ebd61 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -123,7 +123,7 @@ public static UAuthority remote(InetAddress device) { /** * Static factory method for creating an empty authority, to avoid working with null
- * @return Returns an empty altifi authority that has no domain or device information. + * @return Returns an empty authority that has no domain or device information. */ public static UAuthority empty() { return EMPTY; @@ -206,11 +206,11 @@ public enum AddressType { private final int value; - AddressType(int value) { + private AddressType(int value) { this.value = value; } - int getValue() { + public int getValue() { return value; } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index b2a09ed7..e5efd077 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -158,4 +158,5 @@ public Optional id(Integer id) { } return Optional.ofNullable(this.id); } -} + +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index a14d56f6..877406c6 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -30,7 +30,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.util.Arrays; import java.util.Optional; @@ -43,6 +42,13 @@ */ public interface UriFactory { + static final int LOCAL_MICRO_URI_LENGTH = 8; // local micro URI length + + static final int IPV4_MICRO_URI_LENGTH = 12; // IPv4 micro URI length + + static final int IPV6_MICRO_URI_LENGTH = 24; // IPv6 micro Uri length + + /** * Build a Long-URI string from the separate parts of an URI. * @@ -146,59 +152,59 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { return new byte[0]; } - try { - Optional maybeAddress = Uri.uAuthority().address(); - Optional maybeUeId = Uri.uEntity().id(); - Optional maybeUResourceId = Uri.uResource().id(); - if (!maybeUeId.isPresent() || !maybeUResourceId.isPresent()) { - return new byte[0]; - } + Optional maybeAddress = Uri.uAuthority().address(); + Optional maybeUeId = Uri.uEntity().id(); + Optional maybeUResourceId = Uri.uResource().id(); + if (!maybeUeId.isPresent() || !maybeUResourceId.isPresent()) { + return new byte[0]; + } - ByteArrayOutputStream os = new ByteArrayOutputStream(); - // UP_VERSION - os.write(0x1); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + // UP_VERSION + os.write(0x1); - // TYPE - if (Uri.uAuthority().isLocal()) { - os.write(0x0); - } else { - os.write(maybeAddress.get() instanceof Inet4Address ? 1 : 2); - } + // TYPE + if (Uri.uAuthority().isLocal()) { + os.write(0x0); + } else { + os.write(maybeAddress.get() instanceof Inet4Address ? 1 : 2); + } - // URESOURCE_ID - os.write(maybeUResourceId.get()>>8); - os.write(maybeUResourceId.get()); + // URESOURCE_ID + os.write(maybeUResourceId.get()>>8); + os.write(maybeUResourceId.get()); - // UAUTHORITY_ADDRESS - if (!Uri.uAuthority().isLocal()) { + // UAUTHORITY_ADDRESS + if (!Uri.uAuthority().isLocal()) { + try { os.write(maybeAddress.get().getAddress()); + } catch (IOException e) { + return new byte[0]; } + } - // UENTITY_ID - os.write(maybeUeId.get()>>8); - os.write(maybeUeId.get()); - - // UENTITY_VERSION - String version = Uri.uEntity().version().orElse(""); - if (version.isEmpty()) { - os.write((byte)Short.MAX_VALUE>>8); - os.write((byte)Short.MAX_VALUE); + // UENTITY_ID + os.write(maybeUeId.get()>>8); + os.write(maybeUeId.get()); + + // UENTITY_VERSION + String version = Uri.uEntity().version().orElse(""); + if (version.isEmpty()) { + os.write((byte)Short.MAX_VALUE>>8); + os.write((byte)Short.MAX_VALUE); + } else { + String[] parts = version.split("\\."); + if (parts.length > 1) { + int major = (Integer.parseInt(parts[0]) << 3) + (Integer.parseInt(parts[1]) >> 8); + os.write((byte)major); + os.write((byte)Integer.parseInt(parts[1])); } else { - String[] parts = version.split("\\."); - if (parts.length > 1) { - int major = (Integer.parseInt(parts[0]) << 3) + (Integer.parseInt(parts[1]) >> 8); - os.write((byte)major); - os.write((byte)Integer.parseInt(parts[1])); - } else { - os.write(Integer.parseInt(parts[0])<<3); - os.write(0); - } + os.write(Integer.parseInt(parts[0])<<3); + os.write(0); } - return os.toByteArray(); - } - catch (IOException e) { - return new byte[0]; } + return os.toByteArray(); + } /** @@ -401,7 +407,7 @@ private static UResource buildResource(String resourceString) { * @return Returns an URI data object. */ static UUri parseFromMicroUri(byte[] microUri) { - if (microUri == null || microUri.length < 8 ) { + if (microUri == null || microUri.length < UriFactory.LOCAL_MICRO_URI_LENGTH ) { return UUri.empty(); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java index 32b0dfc1..9eef880e 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java @@ -25,6 +25,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.datamodel.UAuthority.AddressType; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -33,6 +34,7 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Arrays; class UriFactoryTest { @@ -1082,9 +1084,9 @@ public void test_build_micro_uri_from_local_uri_simple_version() { UResource uResource = new UResource("door", "front_left", "Door", (short)3); byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(8, uProtocolUri.length); + assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(0, uProtocolUri[1]); // local + assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) @@ -1101,9 +1103,9 @@ public void test_build_micro_uri_from_local_uri() { UResource uResource = new UResource("door", "front_left", "Door", (short)3); byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(8, uProtocolUri.length); + assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(0, uProtocolUri[1]); // local + assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) @@ -1120,9 +1122,9 @@ public void test_build_micro_uri_from_local_uri_large_minor_version() { UResource uResource = new UResource("door", "front_left", "Door", (short)3); byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(8, uProtocolUri.length); + assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(0, uProtocolUri[1]); // local + assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) @@ -1140,9 +1142,9 @@ public void test_build_micro_uri_from_local_uri_no_version() { UResource uResource = new UResource("door", "front_left", "Door", (short)3); byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(8, uProtocolUri.length); + assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(0, uProtocolUri[1]); // local + assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) @@ -1164,6 +1166,97 @@ public void test_build_micro_uri_from_local_uri_then_parse_back_to_uri() { assertEquals(use, Uri.uEntity()); assertEquals(uResource, Uri.uResource()); } + + @Test + @DisplayName("Test Create a uProtocol Micro URI for remote IPv4 UAuthority") + public void test_build_micro_uri_from_remote_ipv4_address() throws UnknownHostException { + final InetAddress address = InetAddress.getByName("127.0.0.1"); + final UAuthority uAuthority = UAuthority.remote(address); + final UEntity use = new UEntity("", null, (short)5); + final UResource uResource = UResource.fromId((short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + assertEquals(UriFactory.IPV4_MICRO_URI_LENGTH, uProtocolUri.length); + assertEquals(1, uProtocolUri[0]); // version 1 + assertEquals(AddressType.IPv4.getValue(), uProtocolUri[1]); // IPv4 + assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) + assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) + InetAddress address2 = InetAddress.getByAddress(Arrays.copyOfRange(uProtocolUri, 4, 8)); + assertEquals(address, address2); + assertEquals(0, uProtocolUri[8]); // UEntity ID (MSB) + assertEquals(5, uProtocolUri[9]); // UEntity ID (LSB) + assertEquals((byte)Short.MAX_VALUE>>8, uProtocolUri[10]); // UEntity Version (MSB) + assertEquals((byte)Short.MAX_VALUE, uProtocolUri[11]); // UEntity Version (LSB) + } + @Test + @DisplayName("Test Create a uProtocol Micro URI for remote IPv6 UAuthority") + public void test_build_micro_uri_from_remote_ipv6_address() throws UnknownHostException { + final InetAddress address = InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"); + final UAuthority uAuthority = UAuthority.remote(address); + final UEntity use = new UEntity("", null, (short)5); + final UResource uResource = UResource.fromId((short)3); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + assertEquals(UriFactory.IPV6_MICRO_URI_LENGTH, uProtocolUri.length); + assertEquals(1, uProtocolUri[0]); // version 1 + assertEquals(AddressType.IPv6.getValue(), uProtocolUri[1]); // IPv4 + assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) + assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) + InetAddress address2 = InetAddress.getByAddress(Arrays.copyOfRange(uProtocolUri, 4, 20)); + assertEquals(address, address2); + assertEquals(0, uProtocolUri[20]); // UEntity ID (MSB) + assertEquals(5, uProtocolUri[21]); // UEntity ID (LSB) + assertEquals((byte)Short.MAX_VALUE>>8, uProtocolUri[22]); // UEntity Version (MSB) + assertEquals((byte)Short.MAX_VALUE, uProtocolUri[23]); // UEntity Version (LSB) + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI with null URI") + public void test_build_micro_uri_from_null_uri() { + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(null); + assertEquals(0, uProtocolUri.length); + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI with empty URI") + public void test_build_micro_uri_from_empty_uri() { + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(UUri.empty()); + assertEquals(0, uProtocolUri.length); + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI without UResource id") + public void test_build_micro_uri_from_uri_missing_uresource_id() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = new UEntity("body.access", "1", (short)5); + UResource uResource = UResource.empty(); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + + assertEquals(0, uProtocolUri.length); + } + + @Test + @DisplayName("Test Create a uProtocol Micro URI with invalid address") + public void test_build_micro_uri_from_uri_invalid_address() throws UnknownHostException { + InetAddress address = InetAddress.getByName("example.com"); + UAuthority uAuthority = UAuthority.remote(address); + UEntity use = new UEntity("body.access", "1", (short)5); + UResource uResource = UResource.fromName("door"); + + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + + assertEquals(0, uProtocolUri.length); + } + + @Test + @DisplayName("Test parse micro URI from empty byte[]") + public void test_parse_micro_uri_from_empty_byte_array() { + byte[] uProtocolUri = new byte[0]; + UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); + assertEquals(UUri.empty(), Uri); + } + } \ No newline at end of file From a62577437a41a14a99e116bf90f79ce25afa82fa Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Thu, 7 Sep 2023 12:37:15 +0300 Subject: [PATCH 15/52] testing UStatus a bit more --- .../utransport/datamodel/UStatusTest.java | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java index 7db61427..eacda56a 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java @@ -5,7 +5,9 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.HashSet; import java.util.Optional; +import java.util.Set; import static org.junit.jupiter.api.Assertions.*; @@ -14,12 +16,45 @@ class UStatusTest { @Test @DisplayName("Make sure the equals and hash code works") public void testHashCodeEquals() { - // can't test equals and hashcode for private classes - need to figure this out EqualsVerifier.forClass(UStatus.class) .suppress(Warning.INHERITED_DIRECTLY_FROM_OBJECT) .usingGetClass().verify(); } + @Test + @DisplayName("Make sure the equals and hash code for ok scenarios") + public void testHashCodeEquals_ok_scenarios() { + // Sets call equals and hash code - using them to test functionality + Set statuses = new HashSet<>(); + statuses.add(UStatus.ok()); + statuses.add(UStatus.ok()); + statuses.add(UStatus.ok("ackId")); + statuses.add("5"); + + assertEquals(3, statuses.size()); + } + + @Test + @DisplayName("Make sure the equals and hash code for fail scenarios") + public void testHashCodeEquals_fail_scenarios() { + // Sets call equals and hash code - using them to test functionality + Set statuses = new HashSet<>(); + // these two are the same + statuses.add(UStatus.failed()); + statuses.add(UStatus.failed()); + + // these two are the same + statuses.add(UStatus.failed("boom")); + statuses.add(UStatus.failed("boom", UStatus.Code.UNKNOWN)); + + statuses.add(UStatus.failed("bam")); + statuses.add(UStatus.failed("boom", UStatus.Code.UNSPECIFIED.value())); + statuses.add(UStatus.failed("boom", UStatus.Code.INVALID_ARGUMENT)); + statuses.add("5"); + + assertEquals(6, statuses.size()); + } + @Test @DisplayName("Make sure the toString works on ok status") public void testToString_for_ok_status() { From b83985f6709ba74f9411eaa05e7cd534ff4e88fa Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Thu, 7 Sep 2023 23:46:52 +0300 Subject: [PATCH 16/52] working on UAttributes --- .../utransport/datamodel/UAttributes.java | 94 +++--- .../validate/UAttributesValidator.java | 38 ++- .../utransport/datamodel/UAttributeTest.java | 78 ++++- .../validator/UAttributesValidatorTest.java | 303 +++++++----------- 4 files changed, 279 insertions(+), 234 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 0c87f9ca..7d0bdd69 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -21,11 +21,19 @@ package org.eclipse.uprotocol.utransport.datamodel; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import org.eclipse.uprotocol.uri.datamodel.UUri; +/** + * When sending data over uTransport the basic API for send uses a source topic and the UPayload as the data. + * Any other information about the message is placed in the UAttributes class. + * The UAttributes class holds the additional information along with business methods for understanding more about the actual message sent. + * add all the functionality that I would have if I had strong objects such as UMessage + * + */ public class UAttributes { private static final UAttributes EMPTY = new UAttributes(null, null, null, null, null, null, null, null, null); @@ -52,7 +60,6 @@ public class UAttributes { * @param priority Message priority * @param ttl Time to live in milliseconds * @param token Authorization token used for TAP - * @param hint Hint regarding the bytes contained within the UPayload * @param sink Explicit destination URI * @param plevel Permission Level * @param commstatus Communication Status @@ -79,8 +86,8 @@ private UAttributes(UAttributesBuilder builder) { /** - * Static factory method for creating an empty ultifi cloud event attributes object, to avoid working with null. - * @return Returns an empty transport attributes that indicates that there are no added additional attributes to configure. + * Static factory method for creating an empty attributes object, to avoid working with null. + * @return Returns an empty attributes that indicates that there are no added additional attributes to configure. */ public static UAttributes empty() { return EMPTY; @@ -117,8 +124,9 @@ public UPriority priority() { } /** - * hint regarding the bytes contained within the UPayload. - * @return Returns an Optional hint regarding the bytes contained within the UPayload. + * A time to live which is how long this event should live for after it was generated (in milliseconds). + * Events without this attribute (or value is 0) MUST NOT timeout. + * @return An Optional time to live which is how long this event should live for after it was generated (in milliseconds). */ public Optional ttl() { return ttl == null ? Optional.empty() : Optional.of(this.ttl); @@ -142,8 +150,8 @@ public Optional sink() { } /** - * The reqid is used to return a response for a specific request. - * @return Returns an Optional requestId attribute. + * The reqid is used to indicate a response for a specific request. + * @return Returns an Optional requestId that indicates that this is a response for a specific request. */ public Optional reqid() { return reqid == null ? Optional.empty() : Optional.of(reqid); @@ -159,21 +167,52 @@ public Optional plevel() { /** * The communication status of the message. - * @return Returns an Optional communication status attribute. + * @return Returns an Optional communication status attribute that indicates an error from the platform. */ public Optional commstatus() { return commstatus == null ? Optional.empty() : Optional.of(commstatus); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UAttributes that = (UAttributes) o; + return Objects.equals(id, that.id) && type == that.type + && priority == that.priority && Objects.equals(ttl, that.ttl) + && Objects.equals(token, that.token) && Objects.equals(sink, that.sink) + && Objects.equals(plevel, that.plevel) && Objects.equals(commstatus, that.commstatus) + && Objects.equals(reqid, that.reqid); + } + + @Override + public int hashCode() { + return Objects.hash(id, type, priority, ttl, token, sink, plevel, commstatus, reqid); + } + + @Override + public String toString() { + return "UAttributes{" + + "id=" + id + + ", type=" + type + + ", priority=" + priority + + ", ttl=" + ttl + + ", token='" + token + '\'' + + ", sink=" + sink + + ", plevel=" + plevel + + ", commstatus=" + commstatus + + ", reqid=" + reqid + + '}'; + } /** * Builder for the UAttributes object. */ public static class UAttributesBuilder { - private UUID id; - private UMessageType type; - private UPriority priority; + private final UUID id; + private final UMessageType type; + private final UPriority priority; private Integer ttl; private String token; private UUri sink; @@ -181,36 +220,10 @@ public static class UAttributesBuilder { private Integer commstatus; private UUID reqid; - public UAttributesBuilder() {} - - /** - * Add uProtocol Prioritization classifications. - * @param priority the uProtocol Prioritization classifications. - * @return Returns the UAttributesBuilder with the configured Priority. - */ - public UAttributesBuilder withPriority(UPriority priority) { - this.priority = priority; - return this; - } - - /** - * Add the unique identifier for the message. - * @param id the unique identifier for the message. - * @return Returns the UAttributesBuilder with the configured id. - */ - public UAttributesBuilder withId(UUID id) { + public UAttributesBuilder(UUID id, UMessageType type, UPriority priority) { this.id = id; - return this; - } - - /** - * Add the message type. - * @param type the message type. - * @return Returns the UAttributesBuilder with the configured type. - */ - public UAttributesBuilder withType(UMessageType type) { - this.type = type; - return this; + this. type = type; + this.priority = priority; } /** @@ -278,7 +291,6 @@ public UAttributesBuilder withReqId(UUID reqid) { * @return Returns a constructed UAttributes. */ public UAttributes build() { - // validation if needed return new UAttributes(this); } } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java index 0b9961aa..fce3b6f0 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java @@ -186,36 +186,46 @@ public UStatus validateReqId(UAttributes attributes) { /** - * PUBLISH UAttributes Validator - * + * Implements validations for UAttributes that define a message that is meant for publishing state changes. */ private static class Publish extends UAttributesValidator { /** - * Validate UAttributes with type UMessageType PUBLISH + * Validates that attributes for a message meant to publish state changes has the correct type. * @param attributes UAttributes to validate - * @return Returns a UStatus indicating if the MessageType is valid or not. + * @return Returns a UStatus indicating if the MessageType is of the correct type. */ @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.PUBLISH ? UStatus.ok() : UStatus.failed("Wrong Attribute Type", Code.INVALID_ARGUMENT.value()); + return attributes.type() == UMessageType.PUBLISH ? UStatus.ok() : + UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); + } + + @Override + public String toString() { + return "UAttributesValidator.Publish"; } } /** - * Validate UAttributes with type UMessageType Request + * Implements validations for UAttributes that define a message that is meant for an RPC request. */ private static class Request extends UAttributesValidator { + /** + * Validates that attributes for a message meant for an RPC request has the correct type. + * @param attributes UAttributes to validate. + * @return Returns a UStatus indicating if the MessageType is of the correct type. + */ @Override public UStatus validateType(UAttributes attributes) { return attributes.type() == UMessageType.REQUEST ? UStatus.ok() : - UStatus.failed("Wrong Attribute Type", Code.INVALID_ARGUMENT.value()); + UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); } /** - * Validate the sink Uri. - * @param attributes + * Validates that attributes for a message meant for an RPC request has a destination sink. + * @param attributes Attributes to validate. * @return Returns a UStatus indicating if the Uri is valid or not. */ @Override @@ -242,6 +252,11 @@ public UStatus validateTtl(UAttributes attributes) { return ttl.get() > 0 ? UStatus.ok() : UStatus.failed("Invalid TTL", Code.INVALID_ARGUMENT.value()); } } + + @Override + public String toString() { + return "UAttributesValidator.Request"; + } } @@ -286,6 +301,11 @@ public UStatus validateReqId(UAttributes attributes) { return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); } + + @Override + public String toString() { + return "UAttributesValidator.Response"; + } } } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index 1449303f..2596c3c2 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -21,15 +21,83 @@ package org.eclipse.uprotocol.utransport.datamodel; -import org.junit.Test; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; public class UAttributeTest { - + @Test - @DisplayName("test UAttributesBuilder") - public void test_uattributesbuilder() { - + @DisplayName("Make sure the equals and hash code works") + public void testHashCodeEquals() { + EqualsVerifier.forClass(UAttributes.class).usingGetClass().verify(); } + + @Test + @DisplayName("Make sure the toString works on empty") + public void testToString_with_empty() { + UAttributes uAttributes = UAttributes.empty(); + assertEquals("UAttributes{id=null, type=null, priority=null, ttl=null, token='null', sink=null, plevel=null, commstatus=null, reqid=null}", + uAttributes.toString()); + } + + @Test + @DisplayName("Make sure the toString works") + public void testToString() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUID requestId = UUID.randomUUID(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.LOW) + .withSink(new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.empty())) + .withTtl(1000) + .withToken("someToken") + .withPermissionLevel(1) + .withReqId(requestId) + .withCommStatus(5) + .build(); + assertEquals(String.format("UAttributes{id=%s, type=RESPONSE, priority=LOW, ttl=1000, token='someToken', " + + "sink=Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + + "uEntity=UEntity{name='body.access', version='latest', id='unknown'}, " + + "uResource=UResource{name='', instance='null', message='null', id='unknown'}}, " + + "plevel=1, commstatus=5, reqid=%s}", + id,requestId), + uAttributes.toString()); + } + + @Test + @DisplayName("Test creating a complete UAttributes") + public void testCreatingUattributes() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUID requestId = UUID.randomUUID(); + final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.empty()); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .withToken("someToken") + .withPermissionLevel(1) + .withReqId(requestId) + .withCommStatus(5) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertEquals(sink, uAttributes.sink().orElse(UUri.empty())); + assertEquals(1000, uAttributes.ttl().orElse(0)); + assertEquals(1, uAttributes.plevel().orElse(3)); + assertEquals("someToken", uAttributes.token().orElse("")); + assertEquals(5, uAttributes.commstatus().orElse(0)); + assertEquals(requestId, uAttributes.reqid().orElse(UUID.randomUUID())); + } + } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index 1480deab..1e9dcede 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -21,25 +21,24 @@ package org.eclipse.uprotocol.utransport.validator; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.UUID; - import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.factory.UriFactory; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; import org.eclipse.uprotocol.utransport.datamodel.UPriority; import org.eclipse.uprotocol.utransport.datamodel.UStatus; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; import org.eclipse.uprotocol.utransport.validate.UAttributesValidator; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + class UAttributesValidatorTest { @@ -47,100 +46,42 @@ class UAttributesValidatorTest { @DisplayName("test fetching validator for valid types") public void test_fetching_validator_for_valid_types() { - UAttributesValidator publish = UAttributesValidator.getValidator(new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .withType(UMessageType.PUBLISH) - .build()); - assert(publish instanceof UAttributesValidator); - - UAttributesValidator request = UAttributesValidator.getValidator(new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .withType(UMessageType.REQUEST) - .build()); - assert(request instanceof UAttributesValidator); - - UAttributesValidator response = UAttributesValidator.getValidator(new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .withType(UMessageType.RESPONSE) - .build()); - assert(response instanceof UAttributesValidator); - - UAttributesValidator invalid = UAttributesValidator.getValidator(new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .build()); - assert(invalid instanceof UAttributesValidator); - } + UAttributesValidator publish = UAttributesValidator.getValidator( + new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW).build()); + assertEquals("UAttributesValidator.Publish", publish.toString()); - @Test - @DisplayName("test validating invalid types") - public void test_validator_invalid_types() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .build(); + UAttributesValidator request = UAttributesValidator.getValidator( + new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.LOW).build()); + assertEquals("UAttributesValidator.Request", request.toString()); - final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); - assert(validator instanceof UAttributesValidator); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Wrong Attribute Type"); + UAttributesValidator response = UAttributesValidator.getValidator( + new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.LOW).build()); + assertEquals("UAttributesValidator.Response", response.toString()); } - @Test @DisplayName("test validating_valid_publish_messagetypes") public void test_validating_valid_publish_messagetypes() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .withType(UMessageType.PUBLISH) - .build(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); - assert(validator instanceof UAttributesValidator); final UStatus status = validator.validate(attributes); assertTrue(status.isSuccess()); assertEquals(status.msg(), "ok"); } - @Test - @DisplayName("test validating invalid priority attribute") - public void test_validating_invalid_priority_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withPriority(null) - .build(); - - final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - - final UStatus status = validator.validatePriority(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid Priority"); - } - - @Test - @DisplayName("test validating valid priority attribute") - public void test_validating_valid_priority_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withPriority(UPriority.LOW) - .build(); - - final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validatePriority(attributes); - assertEquals(status, UStatus.ok()); - } @Test @DisplayName("test validating publish invalid ttl attribute") public void test_validating_publish_invalid_ttl_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withTtl(-1) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(-1).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateTtl(attributes); @@ -152,9 +93,10 @@ public void test_validating_publish_invalid_ttl_attribute() { @Test @DisplayName("test validating publish valid ttl attribute") public void test_validating_valid_ttl_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withTtl(100) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(100).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateTtl(attributes); @@ -164,12 +106,12 @@ public void test_validating_valid_ttl_attribute() { @Test @DisplayName("test validating invalid id attribute") public void test_validating_invalid_id_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withId(null) - .build(); - final UAttributes attributes1 = new UAttributesBuilder() - .withId(UUID.randomUUID()) - .build(); + + final UAttributes attributes = new UAttributesBuilder(null, + UMessageType.PUBLISH, UPriority.LOW).build(); + + final UAttributes attributes1 = new UAttributesBuilder(UUID.randomUUID(), + UMessageType.PUBLISH, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); UStatus status = validator.validateId(attributes); @@ -177,18 +119,17 @@ public void test_validating_invalid_id_attribute() { assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); assertEquals(status.msg(), "Invalid UUID"); - status = validator.validateId(attributes1); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid UUID"); + UStatus status1 = validator.validateId(attributes1); + assertTrue(status1.isFailed()); + assertEquals(status1.getCode(), Code.INVALID_ARGUMENT.value()); + assertEquals(status1.msg(), "Invalid UUID"); } @Test @DisplayName("test validating valid id attribute") public void test_validating_valid_id_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .build(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateId(attributes); @@ -199,9 +140,8 @@ public void test_validating_valid_id_attribute() { @DisplayName("test validating invalid sink attribute") public void test_validating_invalid_sink_attribute() { final UUri uri = UriFactory.parseFromUri("//"); - final UAttributes attributes = new UAttributesBuilder() - .withSink(uri) - .build(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateSink(attributes); @@ -215,9 +155,8 @@ public void test_validating_invalid_sink_attribute() { @DisplayName("test validating valid sink attribute") public void test_validating_valid_sink_attribute() { final UUri uri = UriFactory.parseFromUri("/haartley/1"); - final UAttributes attributes = new UAttributesBuilder() - .withSink(uri) - .build(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateSink(attributes); @@ -227,9 +166,9 @@ public void test_validating_valid_sink_attribute() { @Test @DisplayName("test validating invalid ReqId attribute") public void test_validating_invalid_ReqId_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withReqId(UUID.randomUUID()) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW).withReqId(UUID.randomUUID()).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateReqId(attributes); @@ -241,9 +180,11 @@ public void test_validating_invalid_ReqId_attribute() { @Test @DisplayName("test validating valid ReqId attribute") public void test_validating_valid_ReqId_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateReqId(attributes); @@ -254,9 +195,11 @@ public void test_validating_valid_ReqId_attribute() { @Test @DisplayName("test validating invalid PermissionLevel attribute") public void test_validating_invalid_PermissionLevel_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withPermissionLevel(-1) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withPermissionLevel(-1) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validatePermissionLevel(attributes); @@ -268,9 +211,10 @@ public void test_validating_invalid_PermissionLevel_attribute() { @Test @DisplayName("test validating valid PermissionLevel attribute") public void test_validating_valid_PermissionLevel_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withPermissionLevel(0) - .build(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withPermissionLevel(0) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validatePermissionLevel(attributes); @@ -280,9 +224,11 @@ public void test_validating_valid_PermissionLevel_attribute() { @Test @DisplayName("test validating invalid commstatus attribute") public void test_validating_invalid_commstatus_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withCommStatus(100) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withCommStatus(100) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateCommStatus(attributes); @@ -294,9 +240,11 @@ public void test_validating_invalid_commstatus_attribute() { @Test @DisplayName("test validating valid commstatus attribute") public void test_validating_valid_commstatus_attribute() { - final UAttributes attributes = new UAttributesBuilder() - .withCommStatus(Code.ABORTED.value()) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withCommStatus(Code.ABORTED.value()) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateCommStatus(attributes); @@ -308,16 +256,15 @@ public void test_validating_valid_commstatus_attribute() { @DisplayName("test validating request message types") public void test_validating_request_message_types() { final UUri sink = UriFactory.parseFromUri("/hartley/1/rpc.response"); - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.NETWORK_CONTROL) - .withType(UMessageType.REQUEST) - .withSink(sink) - .withTtl(100) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.NETWORK_CONTROL) + .withSink(sink) + .withTtl(100) + .build(); final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Request", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isSuccess()); assertEquals(status.msg(), "ok"); @@ -326,31 +273,31 @@ public void test_validating_request_message_types() { @Test @DisplayName("test validating request validator using wrong messagetype") public void test_validating_request_validator_with_wrong_messagetype() { - final UAttributes attributes = new UAttributesBuilder() - .withType(UMessageType.PUBLISH) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.NETWORK_CONTROL) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Request", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Wrong Attribute Type,Invalid UUID,Missing Sink,Invalid Priority,Missing TTL"); + assertEquals("Wrong Attribute Type [PUBLISH],Missing Sink,Missing TTL", status.msg()); } @Test @DisplayName("test validating request validator using bad ttl") public void test_validating_request_validator_with_wrong_bad_ttl() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) - .withPriority(UPriority.NETWORK_CONTROL) - .withType(UMessageType.REQUEST) - .withTtl(-1) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.NETWORK_CONTROL) + .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withTtl(-1) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Request", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); @@ -360,17 +307,16 @@ public void test_validating_request_validator_with_wrong_bad_ttl() { @Test @DisplayName("test validating response validator using bad ttl") public void test_validating_response_validator_with_wrong_bad_ttl() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) - .withPriority(UPriority.NETWORK_CONTROL) - .withTtl(-1) - .withType(UMessageType.RESPONSE) - .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) + .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withTtl(-1) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Response", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); @@ -380,17 +326,16 @@ public void test_validating_response_validator_with_wrong_bad_ttl() { @Test @DisplayName("test validating response validator using bad UUID") public void test_validating_response_validator_with_bad_reqid() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) - .withPriority(UPriority.NETWORK_CONTROL) - .withTtl(100) - .withType(UMessageType.RESPONSE) - .withReqId(UUID.randomUUID()) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUID.randomUUID(), + UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) + .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withTtl(100) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Response", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); @@ -401,46 +346,46 @@ public void test_validating_response_validator_with_bad_reqid() { @Test @DisplayName("test validating publish validator with wrong messagetype") public void test_validating_publish_validator_with_wrong_messagetype() { - final UAttributes attributes = new UAttributesBuilder() - .withType(UMessageType.REQUEST) - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.NETWORK_CONTROL) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Publish", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Wrong Attribute Type,Invalid UUID,Invalid Priority"); + assertEquals("Wrong Attribute Type [REQUEST]", status.msg()); } @Test @DisplayName("test validating response validator with wrong messagetype") public void test_validating_response_validator_with_wrong_messagetype() { - final UAttributes attributes = new UAttributesBuilder() - .withType(UMessageType.PUBLISH) - .build(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.NETWORK_CONTROL) + .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Response", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid Type,Invalid UUID,Missing Sink,Invalid Priority,Missing correlationId"); + assertEquals("Invalid Type,Missing Sink,Missing correlationId", status.msg()); } @Test @DisplayName("test validating request containing token") public void test_validating_request_containing_token() { - final UAttributes attributes = new UAttributesBuilder() - .withId(UUIDFactory.Factories.UPROTOCOL.factory().create()) - .withPriority(UPriority.LOW) - .withType(UMessageType.PUBLISH) - .withToken("null") - .build(); + + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withToken("null") + .build(); final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); - assert(validator instanceof UAttributesValidator); + assertEquals("UAttributesValidator.Publish", validator.toString()); final UStatus status = validator.validate(attributes); assertEquals(status, UStatus.ok()); } From 92eb9c95f4bfdf9568048ed5a5cd33c0479ceb6d Mon Sep 17 00:00:00 2001 From: czfdcn Date: Fri, 8 Sep 2023 15:16:35 -0400 Subject: [PATCH 17/52] More coverage for UUri updates --- pom.xml | 6 + .../uprotocol/uri/datamodel/UAuthority.java | 14 +- .../uprotocol/uri/datamodel/UEntity.java | 13 +- .../uprotocol/uri/datamodel/UResource.java | 18 ++- .../uprotocol/uri/factory/UriFactory.java | 60 +++++++-- .../uprotocol/uri/validator/UriValidator.java | 34 ++++- .../uri/datamodel/UAuthorityTest.java | 4 +- .../uprotocol/uri/datamodel/UEntityTest.java | 6 +- .../uri/datamodel/UResourceTest.java | 4 +- .../uprotocol/uri/datamodel/UUriTest.java | 12 +- .../uprotocol/uri/factory/UriFactoryTest.java | 123 ++++++++++++++++-- .../uri/validator/UriValidatorTest.java | 32 +++++ 12 files changed, 283 insertions(+), 43 deletions(-) diff --git a/pom.xml b/pom.xml index 40d1f7ab..8538dbe4 100644 --- a/pom.xml +++ b/pom.xml @@ -239,6 +239,12 @@ 5.1.2 + + commons-validator + commons-validator + 1.7 + + \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index ac3ebd61..760e11b3 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.Objects; import java.util.Optional; +import org.apache.commons.validator.routines.InetAddressValidator; /** * Data representation of an Authority.
An Authority consists of a device and a domain.
@@ -72,7 +73,16 @@ public class UAuthority { private UAuthority(String device, String domain, boolean markedRemote) { this.device = device == null ? null : device.toLowerCase(); this.domain = domain == null ? null : domain.toLowerCase(); - this.address = null; + try { + if ((device != null) && InetAddressValidator.getInstance().isValid(device)) { + this.address = InetAddress.getByName(device); + } else { + this.address = null; + } + } catch (Exception e) { + throw new IllegalArgumentException("Invalid device name: " + device, e); + } + this.markedRemote = markedRemote; } @@ -83,7 +93,7 @@ private UAuthority(String device, String domain, boolean markedRemote) { * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. */ private UAuthority(InetAddress address, boolean markedRemote) { - this.device = null; + this.device = address != null ? address.getHostAddress() : null; this.domain = null; this.address = address; this.markedRemote = markedRemote; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index e8ffa80c..78c4e3f9 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -72,6 +72,17 @@ public static UEntity fromName(String name) { } + /** + * Static factory method for creating a uE using id and version. + * @param version The software version. If not supplied, the latest version of the service will be used. + * @param id The software id. + * @return Returns a UEntity with id but unknown name. + */ + public static UEntity fromId(String version, Short id) { + return new UEntity("unknown", version, id); + } + + /** * Static factory method for creating an empty software entity, to avoid working with null
* @return Returns an empty software entity that has a blank name and no version information. @@ -129,6 +140,6 @@ public int hashCode() { public String toString() { return "UEntity{" + "name='" + name + '\'' + ", version='" + (version == null ? "latest" : version) + '\'' + - ", id='" + (id == null ? "unknown" : id) + '\'' + '}'; + ", id='" + (id == null ? "null" : id) + '\'' + '}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index a941c397..8db0bf9b 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -114,11 +114,23 @@ public static UResource fromNameWithInstance(String name, String instance) { /** * Static factory method for creating an Resource using a resource command name such as UpdateDoor. * @param commandName The RPC command name such as UpdateDoor. - * @return returns an Ulitfi resource used for sending RPC commands. + * @return returns an resource used for sending RPC commands. */ public static UResource forRpc(String commandName) { Objects.requireNonNull(commandName, " Resource must have a command name."); - return new UResource("rpc", commandName, null); + return forRpc(commandName, null); + } + + + /** + * Static factory method for creating an Resource using a resource command and ID. + * @param commandName The RPC command name such as UpdateDoor. + * @param id The RPC command id. + * @return returns an resource used for sending RPC commands. + */ + public static UResource forRpc(String commandName, Short id) { + Objects.requireNonNull(commandName, " Resource must have a command name."); + return new UResource("rpc", commandName, null, id); } /** @@ -216,7 +228,7 @@ public String toString() { "name='" + name + '\'' + ", instance='" + instance + '\'' + ", message='" + message + '\'' + - ", id='" + (id == null ? "unknown" : id) + '\'' + + ", id='" + (id == null ? "null" : id) + '\'' + '}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index 877406c6..c3fd5b73 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -159,6 +159,11 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { return new byte[0]; } + // Remote Uri but the address is missing + if (!maybeAddress.isPresent() && Uri.uAuthority().isRemote()) { + return new byte[0]; + } + ByteArrayOutputStream os = new ByteArrayOutputStream(); // UP_VERSION os.write(0x1); @@ -190,8 +195,8 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { // UENTITY_VERSION String version = Uri.uEntity().version().orElse(""); if (version.isEmpty()) { - os.write((byte)Short.MAX_VALUE>>8); - os.write((byte)Short.MAX_VALUE); + os.write((byte)0); + os.write((byte)0); } else { String[] parts = version.split("\\."); if (parts.length > 1) { @@ -313,9 +318,9 @@ private static String buildAuthorityPartOfUri(UAuthority Authority, boolean shor } /** - * Create an URI data object from a uProtocol string (long or short). - * @param uProtocolUri A String uProtocol URI. - * @return Returns an URI data object. + * Create an UUri data object from a uProtocol string either long or short format. + * @param uProtocolUri A short or long format uProtocol URI. + * @return Returns an UUri data object. */ static UUri parseFromUri(String uProtocolUri) { if (uProtocolUri == null || uProtocolUri.isBlank()) { @@ -379,20 +384,37 @@ static UUri parseFromUri(String uProtocolUri) { } + // Try and fetch the uE ID in the name portion of the string Short maybeUeId = null; if (!useName.isEmpty()) { try { maybeUeId = Short.parseShort(useName); } catch (NumberFormatException e) { maybeUeId = null; + } } - return new UUri(uAuthority, new UEntity(useName, useVersion, maybeUeId), uResource); + return new UUri(uAuthority, (maybeUeId != null) ? UEntity.fromId(useVersion, maybeUeId) : + new UEntity(useName, useVersion, maybeUeId), uResource); } private static UResource buildResource(String resourceString) { String[] parts = resourceString.split("#"); String nameAndInstance = parts[0]; + + // Try and fetch the resource ID if there is one (short form) + Short maybeId = null; + try { + maybeId = Short.parseShort(nameAndInstance); + } catch (NumberFormatException e) { + maybeId = null; + + } + + if (maybeId != null) { + return UResource.fromId(maybeId); + } + String[] nameAndInstanceParts = nameAndInstance.split("\\."); String resourceName = nameAndInstanceParts[0]; String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; @@ -421,11 +443,23 @@ static UUri parseFromMicroUri(byte[] microUri) { Optional maybeAddress = Optional.empty(); Optional type = AddressType.from(microUri[1]); - + + // Validate Type is found if (!type.isPresent()) { return UUri.empty(); } + // Validate that the microUri is the correct length for the type + if (type.get() == AddressType.LOCAL && microUri.length != UriFactory.LOCAL_MICRO_URI_LENGTH) { + return UUri.empty(); + } + else if (type.get() == AddressType.IPv4 && microUri.length != UriFactory.IPV4_MICRO_URI_LENGTH) { + return UUri.empty(); + } + else if (type.get() == AddressType.IPv6 && microUri.length != UriFactory.IPV6_MICRO_URI_LENGTH) { + return UUri.empty(); + } + int index = 4; if (!(type.get() == AddressType.LOCAL)) { try { @@ -440,16 +474,18 @@ static UUri parseFromMicroUri(byte[] microUri) { int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); int ueVersion = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - String ueVersionString = String.valueOf(ueVersion >> 11); - if ((ueVersion & 0x7FF) != 0) { + + if (ueVersion == 0) { + ueVersionString = null; // no version provided + } + else if ((ueVersion & 0x7FF) != 0) { ueVersionString += "." + (ueVersion & 0x7FF); } return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), - new UEntity("", ueVersionString, (short)ueId), + UEntity.fromId(ueVersionString, (short)ueId), UResource.fromId((short)uResourceId)); - } - + } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 82b656d1..4b4ea7b4 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -31,7 +31,7 @@ public static UStatus validate(UUri uri) { /** * Validate a Uri that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. * @param uri Uri to validate. - * @return Returns the ValidationResult containing a success or a failure with the error message. + * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validateRpcMethod(UUri uri) { UStatus status = validate(uri); @@ -49,7 +49,7 @@ public static UStatus validateRpcMethod(UUri uri) { * Validate a Uri that is meant to be used as an RPC response URI. Used in Request source values and Response sink values. * * @param uri Uri to validate. - * @return Returns the ValidationResult containing a success or a failure with the error message. + * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validateRpcResponse(UUri uri) { UStatus status = validate(uri); @@ -66,8 +66,38 @@ public static UStatus validateRpcResponse(UUri uri) { } + /** + * Wrapper to validate explicitly a long form URI + * @param uri Long form URI + * @return Returns UStatus containing a success or a failure with the error message. + */ public static UStatus validateLongUUri(String uri) { final UUri uUri = UriFactory.parseFromUri(uri); return validate(uUri); } + + /** + * Validate that a passed shortUri and microUri are the same. We cannot validate long to short + * without the mapping of names to ids. + * @param shortUri Short form URI + * @param microUri Micro form URI + * @return Returns the UStatus containing a success or a failure with the error message. + */ + public static UStatus validateEqualsShortMicroUri(String shortUri, byte[] microUri) { + final UUri uUri = UriFactory.parseFromUri(shortUri); + final UUri uUriMicro = UriFactory.parseFromMicroUri(microUri); + + if (uUri.isEmpty()) { + return UStatus.failed("Short Uri is invalid.", Code.INVALID_ARGUMENT); + } + if (uUriMicro.isEmpty()) { + return UStatus.failed("Micro Uri is invalid.", Code.INVALID_ARGUMENT); + } + + if (!uUri.equals(uUriMicro)) { + String failure = String.format("Short URI %s and Micro Uri %s are not equal.", uUri.toString(), uUriMicro.toString()); + return UStatus.failed(failure, Code.INVALID_ARGUMENT); + } + return UStatus.ok(); + } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index 627e912c..a323a25e 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -167,7 +167,7 @@ public void test_create_uAuthority_with_valid_ip_address() { InetAddress address = Inet6Address.getLoopbackAddress(); UAuthority remote = UAuthority.remote(address); - String expectedLocal = "UAuthority{device='null', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; + String expectedLocal = "UAuthority{device='127.0.0.1', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; InetAddress address2 = remote.address().get(); assertTrue(remote.address().isPresent()); assertEquals(address, address2); @@ -187,7 +187,7 @@ public void test_create_uAuthority_with_valid_ipv6_address() { } UAuthority remote = UAuthority.remote(address); - String expectedLocal = "UAuthority{device='null', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; + String expectedLocal = "UAuthority{device='2001:db8:85a3:0:0:8a2e:370:7334', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index f52940e1..3e07b665 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -44,11 +44,11 @@ public void testToString() { assertTrue(use.version().isPresent()); assertEquals("1", use.version().get()); - String expected = "UEntity{name='body.access', version='1', id='unknown'}"; + String expected = "UEntity{name='body.access', version='1', id='null'}"; assertEquals(expected, use.toString()); UEntity use1 = UEntity.fromName("body.access"); - assertEquals("UEntity{name='body.access', version='latest', id='unknown'}", use1.toString()); + assertEquals("UEntity{name='body.access', version='latest', id='null'}", use1.toString()); } @Test @@ -131,7 +131,7 @@ public void test_create_use_with_invalid_id() { assertTrue(use.version().isPresent()); assertEquals("1", use.version().get()); assertFalse(use.id().isPresent()); - assertEquals("UEntity{name='body.access', version='1', id='unknown'}", use.toString()); + assertEquals("UEntity{name='body.access', version='1', id='null'}", use.toString()); } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 80e4cadb..e5949135 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -39,7 +39,7 @@ public void testHashCodeEquals() { @DisplayName("Make sure the toString works") public void testToString() { UResource uResource = new UResource("door", "front_left", "Door"); - String expected = "UResource{name='door', instance='front_left', message='Door', id='unknown'}"; + String expected = "UResource{name='door', instance='front_left', message='Door', id='null'}"; assertEquals(expected, uResource.toString()); } @@ -208,7 +208,7 @@ public void test_create_UResource_with_invalid_id() { assertTrue(uResource.message().isPresent()); assertEquals("Door", uResource.message().get()); assertFalse(uResource.id().isPresent()); - assertEquals("UResource{name='door', instance='front_left', message='Door', id='unknown'}", uResource.toString()); + assertEquals("UResource{name='door', instance='front_left', message='Door', id='null'}", uResource.toString()); } @Test diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index ff6ca889..dcfc02b0 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -49,20 +49,20 @@ public void testToString() { UUri uri = new UUri(uAuthorityLocal, use, uResource); String expected = "Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + - "uEntity=UEntity{name='body.access', version='1', id='unknown'}, " + - "uResource=UResource{name='door', instance='front_left', message='null', id='unknown'}}"; + "uEntity=UEntity{name='body.access', version='1', id='null'}, " + + "uResource=UResource{name='door', instance='front_left', message='null', id='null'}}"; assertEquals(expected, uri.toString()); UUri uriRemote = new UUri(uAuthorityRemote, use, uResource); String expectedRemote = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + - "uEntity=UEntity{name='body.access', version='1', id='unknown'}, " + - "uResource=UResource{name='door', instance='front_left', message='null', id='unknown'}}"; + "uEntity=UEntity{name='body.access', version='1', id='null'}, " + + "uResource=UResource{name='door', instance='front_left', message='null', id='null'}}"; assertEquals(expectedRemote, uriRemote.toString()); UUri uri2 = new UUri(uAuthorityRemote, use, UResource.empty()); String expectedUri2 = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + - "uEntity=UEntity{name='body.access', version='1', id='unknown'}, " + - "uResource=UResource{name='', instance='null', message='null', id='unknown'}}"; + "uEntity=UEntity{name='body.access', version='1', id='null'}, " + + "uResource=UResource{name='', instance='null', message='null', id='null'}}"; assertEquals(expectedUri2, uri2.toString()); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java index 9eef880e..376cc50a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java @@ -1149,15 +1149,15 @@ public void test_build_micro_uri_from_local_uri_no_version() { assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) - assertEquals((byte)Short.MAX_VALUE>>8, uProtocolUri[6]); // UEntity Version (MSB) - assertEquals((byte)Short.MAX_VALUE, uProtocolUri[7]); // UEntity Version (LSB) + assertEquals((byte)0, uProtocolUri[6]); // UEntity Version (MSB) + assertEquals((byte)0, uProtocolUri[7]); // UEntity Version (LSB) } @Test @DisplayName("Test Create a uProtocol Micro URI to byte[] then call parseFromMicroUri to convert back to UUri") public void test_build_micro_uri_from_local_uri_then_parse_back_to_uri() { UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("", "1.599", (short)5); + UEntity use = UEntity.fromId("1.599", (short)5); UResource uResource = UResource.fromId((short)3); byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); @@ -1172,7 +1172,7 @@ public void test_build_micro_uri_from_local_uri_then_parse_back_to_uri() { public void test_build_micro_uri_from_remote_ipv4_address() throws UnknownHostException { final InetAddress address = InetAddress.getByName("127.0.0.1"); final UAuthority uAuthority = UAuthority.remote(address); - final UEntity use = new UEntity("", null, (short)5); + final UEntity use = UEntity.fromId(null, (short)5); final UResource uResource = UResource.fromId((short)3); byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); @@ -1185,8 +1185,8 @@ public void test_build_micro_uri_from_remote_ipv4_address() throws UnknownHostEx assertEquals(address, address2); assertEquals(0, uProtocolUri[8]); // UEntity ID (MSB) assertEquals(5, uProtocolUri[9]); // UEntity ID (LSB) - assertEquals((byte)Short.MAX_VALUE>>8, uProtocolUri[10]); // UEntity Version (MSB) - assertEquals((byte)Short.MAX_VALUE, uProtocolUri[11]); // UEntity Version (LSB) + assertEquals((byte)0, uProtocolUri[10]); // UEntity Version (MSB) + assertEquals((byte)0, uProtocolUri[11]); // UEntity Version (LSB) } @Test @@ -1194,10 +1194,11 @@ public void test_build_micro_uri_from_remote_ipv4_address() throws UnknownHostEx public void test_build_micro_uri_from_remote_ipv6_address() throws UnknownHostException { final InetAddress address = InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"); final UAuthority uAuthority = UAuthority.remote(address); - final UEntity use = new UEntity("", null, (short)5); + final UEntity use = UEntity.fromId(null, (short)5); final UResource uResource = UResource.fromId((short)3); + final UUri uri = new UUri(uAuthority, use, uResource); - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); + byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(uri); assertEquals(UriFactory.IPV6_MICRO_URI_LENGTH, uProtocolUri.length); assertEquals(1, uProtocolUri[0]); // version 1 assertEquals(AddressType.IPv6.getValue(), uProtocolUri[1]); // IPv4 @@ -1207,8 +1208,10 @@ public void test_build_micro_uri_from_remote_ipv6_address() throws UnknownHostEx assertEquals(address, address2); assertEquals(0, uProtocolUri[20]); // UEntity ID (MSB) assertEquals(5, uProtocolUri[21]); // UEntity ID (LSB) - assertEquals((byte)Short.MAX_VALUE>>8, uProtocolUri[22]); // UEntity Version (MSB) - assertEquals((byte)Short.MAX_VALUE, uProtocolUri[23]); // UEntity Version (LSB) + assertEquals((byte)0, uProtocolUri[22]); // UEntity Version (MSB) + assertEquals((byte)0, uProtocolUri[23]); // UEntity Version (LSB) + final UUri uri2 = UriFactory.parseFromMicroUri(uProtocolUri); + assertEquals(uri.toString(), uri2.toString()); } @Test @@ -1258,5 +1261,105 @@ public void test_parse_micro_uri_from_empty_byte_array() { assertEquals(UUri.empty(), Uri); } + @Test + @DisplayName("Test create and print long, short, and micro URIs using core.usubscription for spec examples") + public void test_create_and_print_long_short_and_micro_uris_using_core_usubscription_for_spec_examples() { + final UEntity ue = new UEntity("core.usubscription", "2", (short)0); + final UResource resource = UResource.forRpc("Subscribe", (short)1); + + UUri Uri = new UUri(UAuthority.local(), ue, resource); + String longUri = UriFactory.buildUProtocolUri(Uri); + String shortUri = UriFactory.buildUProtocolShortUri(Uri); + byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); + assertEquals("/core.usubscription/2/rpc.Subscribe", longUri); + assertEquals("/0/2/1", shortUri); + + System.out.println(Arrays.toString(microUri)); + assertEquals("[1, 0, 0, 1, 0, 0, 16, 0]", Arrays.toString(microUri)); + } + + @Test + @DisplayName("Test create and print remote ipv6_long, short, and micro URIs using core.usubscription for spec examples") + public void test_create_and_print_remote_ipv6_long_short_and_micro_uris_using_core_usubscription_for_spec_examples() throws UnknownHostException { + final UEntity ue = new UEntity("core.usubscription", "2", (short)0); + final UResource resource = UResource.forRpc("Subscribe", (short)1); + final UAuthority authority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); + UUri Uri = new UUri(authority, ue, resource); + String longUri = UriFactory.buildUProtocolUri(Uri); + String shortUri = UriFactory.buildUProtocolShortUri(Uri); + byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); + assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/core.usubscription/2/rpc.Subscribe", longUri); + assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/0/2/1", shortUri); + + System.out.println(Arrays.toString(microUri)); + assertEquals("[1, 2, 0, 1, 32, 1, 13, -72, -123, -93, 0, 0, 0, 0, -118, 46, 3, 112, 115, 52, 0, 0, 16, 0]", Arrays.toString(microUri)); + } + + + @Test + @DisplayName("Test parsing a uProtocol Micro URI with invalid version") + public void test_parsing_micro_uri_bad_version_byte() throws UnknownHostException { + byte[] uProtocolUri = new byte[] {0,0,0,0,0,0,0,0}; + final UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); + assertEquals(UUri.empty(), Uri); + } + + @Test + @DisplayName("Test parsing a uProtocol Micro URI with invalid type") + public void test_parsing_micro_uri_bad_type_byte() throws UnknownHostException { + byte[] uProtocolUri = new byte[] {0x1,0xf,0,0,0,0,0,0}; + final UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); + assertEquals(UUri.empty(), Uri); + } + + @Test + @DisplayName("Test create and convert to and from IPv4 micro URI") + public void test_create_and_convert_to_from_ipv4_micro_uri() throws UnknownHostException { + final UEntity ue = UEntity.fromId("2", (short)0); + final UResource resource = UResource.fromId((short)1); + final UAuthority authority = UAuthority.remote(InetAddress.getByName("192.168.1.100")); + UUri Uri = new UUri(authority, ue, resource); + byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); + UUri uri2 = UriFactory.parseFromMicroUri(microUri); + assertEquals(Uri, uri2); + } + + @Test + @DisplayName("Test parse micro URI using invalid type length") + public void test_parse_micro_uri_using_invalid_type_lengths_address() throws UnknownHostException { + byte[] uProtocolUri = new byte[] {0x1,0x0,0,0,0,0,0,0,0}; + // test local (too large) + UUri uriLocalTest = UriFactory.parseFromMicroUri(uProtocolUri); + assertTrue(uriLocalTest.isEmpty()); + + // test IPv4 (too small) + uProtocolUri[1] = 0x1; + UUri uriIPv4Test = UriFactory.parseFromMicroUri(uProtocolUri); + assertTrue(uriIPv4Test.isEmpty()); + + // Test IPv6 too small + uProtocolUri[1] = 0x2; + UUri uriIPv6Test = UriFactory.parseFromMicroUri(uProtocolUri); + assertTrue(uriIPv6Test.isEmpty()); + } + + @Test + @DisplayName("Test build micro URI with remote authority with no address") + public void test_build_micro_uri_with_remote_authority_with_no_address() throws UnknownHostException { + final UEntity ue = UEntity.fromId("2", (short)0); + final UResource resource = UResource.fromId((short)1); + final UAuthority authority = UAuthority.remote("VCU", null); + UUri Uri = new UUri(authority, ue, resource); + byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); + assertEquals(microUri.length, 0); + } + @Test + @DisplayName("Test parse micro uri with invalid IPv4 address") + public void test_parse_micro_uri_with_invalid_ipv4_address() throws UnknownHostException { + byte[] uProtocolUri = new byte[] {0x1,0x1,-128,-128,-128,-128,0,0}; + UUri uriLocalTest = UriFactory.parseFromMicroUri(uProtocolUri); + assertTrue(uriLocalTest.isEmpty()); + } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index cb70eaf7..b895e924 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -27,6 +27,8 @@ import static org.junit.jupiter.api.Assertions.*; +import java.net.URI; + import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; @@ -156,4 +158,34 @@ public void test_validateLongUUri_with_valid_uri() { final UStatus status = UriValidator.validateLongUUri(uri.uProtocolUri()); assertEquals(UStatus.ok(), status); } + + @Test + @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI are identical") + public void test_validateEqualsShortMicroUri_with_valid_uri() { + final String shortUri = "/0/2/1"; + final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,2<<3,0x0}; + final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); + assertEquals(UStatus.ok(), status); + } + + @Test + @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI are not identical") + public void test_validateEqualsShortMicroUri_with_invalid_uri() { + final String shortUri = "/0/1/1"; + final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x10,0x0}; + final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); + assertEquals("Short URI Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='unknown', version='1', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} and Micro Uri Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='unknown', version='2', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} are not equal.", status.msg()); + } + + @Test + @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI empty values") + public void test_validateEqualsShortMicroUri_with_missing_parameters() { + final String shortUri = "/0/1/1"; + final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x10,0x0}; + final UStatus status = UriValidator.validateEqualsShortMicroUri(null, microUri); + assertEquals("Short Uri is invalid.", status.msg()); + final UStatus status2 = UriValidator.validateEqualsShortMicroUri(shortUri, null); + assertEquals("Micro Uri is invalid.", status2.msg()); + } + } From e48f772ec85e73da14f8b7ed7dd16d7dc3681c06 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Fri, 8 Sep 2023 17:05:55 -0400 Subject: [PATCH 18/52] Added UriFormat definitions --- .../uprotocol/uri/datamodel/LongUri.java | 40 ++++++++++++++++ .../uprotocol/uri/datamodel/MicroUri.java | 39 ++++++++++++++++ .../uprotocol/uri/datamodel/ShortUri.java | 38 +++++++++++++++ .../eclipse/uprotocol/uri/datamodel/UUri.java | 8 ++-- .../uprotocol/uri/datamodel/UriFormat.java | 46 +++++++++++++++++++ .../uprotocol/utransport/UTransport.java | 15 +++--- .../uri/datamodel/UAuthorityTest.java | 8 ++++ .../utransport/datamodel/UAttributeTest.java | 4 +- 8 files changed, 186 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java create mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java create mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java create mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java new file mode 100644 index 00000000..72eae63d --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.datamodel; + +import org.eclipse.uprotocol.uri.factory.UriFactory; + +/** + * Long Format URI + */ +public class LongUri extends UriFormat { + + public LongUri(UUri uri) { + super (UriFactory.buildUProtocolUri(uri), uri); + } + + @Override + public boolean isEmpty() { + return uProtocolUri.isEmpty(); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java new file mode 100644 index 00000000..ed08ce1d --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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. + */ +package org.eclipse.uprotocol.uri.datamodel; + +import org.eclipse.uprotocol.uri.factory.UriFactory; + +/** + * Micro Format uProtocol URI. + */ +public class MicroUri extends UriFormat{ + + public MicroUri(UUri uri) { + super(UriFactory.buildUProtocolMicroUri(uri), uri); + } + + @Override + public boolean isEmpty() { + return uProtocolUri.length == 0; + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java new file mode 100644 index 00000000..5e517373 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.datamodel; + +import org.eclipse.uprotocol.uri.factory.UriFactory; + +public class ShortUri extends UriFormat { + + public ShortUri(UUri uri) { + super(UriFactory.buildUProtocolShortUri(uri), uri); + } + + @Override + public boolean isEmpty() { + return uProtocolUri.isEmpty(); + } + +} + diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index e5efd077..e0ba6b56 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -41,9 +41,9 @@ public class UUri { private static final UUri EMPTY = new UUri(UAuthority.empty(), UEntity.empty(), UResource.empty()); - private final UAuthority uAuthority; - private final UEntity uEntity; - private final UResource uResource; + protected final UAuthority uAuthority; + protected final UEntity uEntity; + protected final UResource uResource; private transient String uProtocolUri; @@ -75,7 +75,7 @@ public UUri(UAuthority uAuthority, UEntity uEntity, String uResource) { /** * Static factory method for creating an empty uri, to avoid working with null
- * @return Returns an empty altifi uri to avoid working with null. + * @return Returns an empty ultify uri to avoid working with null. */ public static UUri empty() { return EMPTY; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java new file mode 100644 index 00000000..15683afc --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java @@ -0,0 +1,46 @@ +package org.eclipse.uprotocol.uri.datamodel; + +/** + * UriFormat is the interface that represents either Long, Short, or micro formats of a uProtocol Uri. + * UriFormat is passed to the transports such that a transport can fix what format they expect to use. + * + * @param The type used for the uProtocol Uri, long and short use String while micro is byte[] + */ +public abstract class UriFormat { + protected final T uProtocolUri; + private final UUri uuri; + + /** + * Constructor for UriFormat called by the child classes (Short, Long, Micro) + * @param uProtocolUri Format specific generated uProtocol URI + * @param uuri UUri data object + */ + protected UriFormat(T uProtocolUri, UUri uuri) { + this.uProtocolUri = uProtocolUri; + this.uuri = uuri; + } + + /** + * Return the uProtocol URI in the correct expected format + * @return uProtocol URI + */ + public T uProtocolUri() { + return uProtocolUri; + } + + /** + * Obtain the UUri that was used to build the Uri Format + * This method might be used if we want to convert from one format to another + * @return UUri data object + */ + public UUri uuri() { + return uuri; + } + + /** + * Check if the UProtocolUri is empty. An empty Uri means that we were not able to + * build it from the UUri. + * @return true if empty, false otherwise + */ + abstract boolean isEmpty(); +} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java index a4b55921..93e80bf3 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java @@ -23,6 +23,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.datamodel.UriFormat; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UListener; import org.eclipse.uprotocol.utransport.datamodel.UPayload; @@ -45,26 +46,28 @@ public interface UTransport { /** * Transmit UPayload to the topic using the attributes defined in UTransportAttributes. - * @param topic UUri receiver of the payload. + * @param + * @param topic UriFormat of a specific type (Long, Short, or Micro) receiver of the payload. * @param payload Actual payload. * @param attributes Additional transport attributes. * @return Returns an Status if managed to send to the underlying communication technology or not. */ - UStatus send(UUri topic, UPayload payload, UAttributes attributes); + UStatus send(UriFormat topic, UPayload payload, UAttributes attributes); /** * Register a method that will be called when a message comes in on the specific topic. - * @param topic UUri of the message that arrived via the underlying transport technology. + * @param topic UriFormat of a specific type (Long, Short, or Micro) of the message that arrived via the underlying transport technology. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is registered successfully. */ - UStatus registerListener(UUri topic, UListener listener); + UStatus registerListener(UriFormat topic, UListener listener); /** * Unregister a method on a topic. Messages arriving on this topic will no longer be processed by this listener. - * @param topic UUri of the messages that will no longer be processed. + * @param topic UriFormat of a specific type (Long, Short, or Micro) of the messages that will no longer be processed. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is removed successfully. + * */ - UStatus unregisterListener(UUri topic, UListener listener); + UStatus unregisterListener(UriFormat topic, UListener listener); } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index a323a25e..952e86a3 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -190,4 +190,12 @@ public void test_create_uAuthority_with_valid_ipv6_address() { String expectedLocal = "UAuthority{device='2001:db8:85a3:0:0:8a2e:370:7334', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } + + @Test + @DisplayName("Test creating uAuthority with valid ipv4 address in the device name") + public void test_create_uAuthority_with_valid_ipv4_address_in_device_name() { + UAuthority remote = UAuthority.remote("192.168.1.100", null); + String expectedLocal = "UAuthority{device='192.168.1.100', domain='null', address='/192.168.1.100', markedRemote=true}"; + assertEquals(expectedLocal, remote.toString()); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index 2596c3c2..1069d419 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -67,8 +67,8 @@ public void testToString() { .build(); assertEquals(String.format("UAttributes{id=%s, type=RESPONSE, priority=LOW, ttl=1000, token='someToken', " + "sink=Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + - "uEntity=UEntity{name='body.access', version='latest', id='unknown'}, " + - "uResource=UResource{name='', instance='null', message='null', id='unknown'}}, " + + "uEntity=UEntity{name='body.access', version='latest', id='null'}, " + + "uResource=UResource{name='', instance='null', message='null', id='null'}}, " + "plevel=1, commstatus=5, reqid=%s}", id,requestId), uAttributes.toString()); From 308751907aed06a160da3056e7a6c149716e1340 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Fri, 8 Sep 2023 17:38:15 -0400 Subject: [PATCH 19/52] Fixing the Generics syntax for uTransport --- .../eclipse/uprotocol/utransport/UTransport.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java index 93e80bf3..dd5540dc 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java @@ -22,7 +22,6 @@ package org.eclipse.uprotocol.utransport; import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.datamodel.UriFormat; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UListener; @@ -32,8 +31,11 @@ /** * 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. + * @param The type of the UriFormat that the UTransport implementation will use. + * @param The primitive type for the UriFormat (string for long/short or byte[] for micro). */ -public interface UTransport { + +public interface UTransport, S> { /** * API to register the calling uE with the underlining transport implementation. @@ -46,28 +48,30 @@ public interface UTransport { /** * Transmit UPayload to the topic using the attributes defined in UTransportAttributes. - * @param + * @param The type of the UriFormat that the UTransport implementation will use. * @param topic UriFormat of a specific type (Long, Short, or Micro) receiver of the payload. * @param payload Actual payload. * @param attributes Additional transport attributes. * @return Returns an Status if managed to send to the underlying communication technology or not. */ - UStatus send(UriFormat topic, UPayload payload, UAttributes attributes); + UStatus send(T topic, UPayload payload, UAttributes attributes); /** * Register a method that will be called when a message comes in on the specific topic. + * @param The type of the UriFormat that the UTransport implementation will use. * @param topic UriFormat of a specific type (Long, Short, or Micro) of the message that arrived via the underlying transport technology. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is registered successfully. */ - UStatus registerListener(UriFormat topic, UListener listener); + UStatus registerListener(T topic, UListener listener); /** * Unregister a method on a topic. Messages arriving on this topic will no longer be processed by this listener. + * @param The type of the UriFormat that the UTransport implementation will use. * @param topic UriFormat of a specific type (Long, Short, or Micro) of the messages that will no longer be processed. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is removed successfully. * */ - UStatus unregisterListener(UriFormat topic, UListener listener); + UStatus unregisterListener(T topic, UListener listener); } \ No newline at end of file From adf77d41780ada93585d8c72a4cd243e23a8a17b Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Sun, 10 Sep 2023 12:51:30 +0300 Subject: [PATCH 20/52] working on UAttributes --- .../utransport/datamodel/UAttributes.java | 118 ++++-- .../utransport/datamodel/UMessageType.java | 11 +- .../utransport/datamodel/UAttributeTest.java | 335 +++++++++++++++++- 3 files changed, 438 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 7d0bdd69..0ad3e250 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -25,14 +25,15 @@ import java.util.Optional; import java.util.UUID; +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; /** * When sending data over uTransport the basic API for send uses a source topic and the UPayload as the data. * Any other information about the message is placed in the UAttributes class. * The UAttributes class holds the additional information along with business methods for understanding more about the actual message sent. - * add all the functionality that I would have if I had strong objects such as UMessage - * */ public class UAttributes { @@ -55,16 +56,15 @@ public class UAttributes { /** * Construct the transport UAttributes object. * - * @param id Unique identifier for the message - * @param type Message type - * @param priority Message priority - * @param ttl Time to live in milliseconds - * @param token Authorization token used for TAP - * @param sink Explicit destination URI - * @param plevel Permission Level - * @param commstatus Communication Status - * @param reqid Request ID - * @return Returns a constructed UAttributes. + * @param id Unique identifier for the message. Required. + * @param type Message type such as Publish a state change, RPC request or RPC response. Required. + * @param priority Message priority. Required. + * @param ttl Time to live in milliseconds. + * @param token Authorization token used for TAP. + * @param sink Explicit destination URI, used in notifications and RPC messages. + * @param plevel Permission Level. + * @param commstatus Communication Status, used to indicate platform communication errors that occurred during delivery. + * @param reqid Request ID, used to indicate the id of the RPC request that matches this RPC response. */ private UAttributes(UUID id, UMessageType type, UPriority priority, Integer ttl, String token, UUri sink, Integer plevel, Integer commstatus, UUID reqid) { @@ -88,15 +88,61 @@ private UAttributes(UAttributesBuilder builder) { /** * Static factory method for creating an empty attributes object, to avoid working with null. * @return Returns an empty attributes that indicates that there are no added additional attributes to configure. + * An empty UAttributes is not valid, in the same way null is not valid, this is because UAttributes has 3 required values - id, type and priority. */ public static UAttributes empty() { return EMPTY; } - public boolean isEmpty() { - return this.id == null && this.type == null && this.priority == null && this.ttl == null && this.token == null - && this.sink == null && this.plevel == null && this.commstatus == null - && this.reqid == null; + /** + * Static factory method for creating a base UAttributes for an RPC request. + * @param id id Unique identifier for the RPC request message. + * @param sink UUri describing the exact RPC command. + * @return Returns a base UAttributes that can be used to build an RPC request. + */ + public static UAttributesBuilder forRpcRequest(UUID id, UUri sink) { + return new UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink); + } + + /** + * Static factory method for creating a base UAttributes for an RPC request. + * @param id Unique identifier for the RPC request message. + * @param uAuthority Indicates where the software for RPC request is installed. + * @param serviceUEntity Indicates what service we want to RPC request to change. + * @param commandName String command name the RPC is executing. + * @return Returns a base UAttributes that can be used to build an RPC request. + */ + public static UAttributesBuilder forRpcRequest(UUID id, UAuthority uAuthority, UEntity serviceUEntity, String commandName) { + return new UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(new UUri(uAuthority, serviceUEntity, UResource.forRpc(commandName))); + } + + /** + * Static factory method for creating a base UAttributes for an RPC response. + * @param id Unique identifier for the RPC response message. + * @param sink UUri describing where the response needs to go. + * @param requestId The UUID of the message that this response is responding to. + * @return Returns a base UAttributes that can be used to build an RPC response. + */ + public static UAttributesBuilder forRpcResponse(UUID id, UUri sink, UUID requestId) { + return new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(requestId); + } + + /** + * Static factory method for creating a base UAttributes for an RPC response. + * @param id Unique identifier for the RPC response message. + * @param uAuthority Indicates where the software for RPC response is for is installed. + * @param callerUEntity Indicates what service called the RPC request and this response is for. + * @param requestId The id of the RPC request that this message is responding to. + * @return Returns a base UAttributes that can be used to build an RPC response. + */ + public static UAttributesBuilder forRpcResponse(UUID id, UAuthority uAuthority, UEntity callerUEntity, UUID requestId) { + return new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(new UUri(uAuthority, callerUEntity, UResource.fromNameWithInstance("rpc", "response"))) + .withReqId(requestId); } /** @@ -108,8 +154,8 @@ public UUID id() { } /** - * Message type. - * @return Returns the message type. + * Message type such as Publish a state change, RPC request or RPC response. + * @return Returns the message type such as Publish a state change, RPC request or RPC response. */ public UMessageType type() { return type; @@ -142,8 +188,8 @@ public Optional token() { /** - * an explicit destination URI. - * @return Returns an Optional destination URI attribute. + * An explicit destination URI, used in notifications and RPC messages. + * @return Returns an Optional destination URI attribute, used in notifications and RPC messages. */ public Optional sink() { return sink == null ? Optional.empty() : Optional.of(sink); @@ -173,6 +219,30 @@ public Optional commstatus() { return commstatus == null ? Optional.empty() : Optional.of(commstatus); } + /** + * Look at the configured UAttributes and determine if the payload could be an RPC Request. + * @return Returns true if the attributes configured indicate that the payload is an RPC Request. + */ + public boolean isRpcRequest() { + return UMessageType.REQUEST.equals(type()) && sink().isPresent(); + } + + /** + * Look at the configured UAttributes and determine if the payload could be an RPC Response. + * @return Returns true if the attributes configured indicate that the payload is an RPC Response. + */ + public boolean isRpcResponse() { + return UMessageType.RESPONSE.equals(type()) && sink().isPresent() && reqid().isPresent(); + } + + /** + * Look at the configured UAttributes and determine of the platform indicated problems. + * @return Returns true if there were platform errors during the operation of uTransport. + */ + public boolean isPlatformTransportSuccess() { + return commstatus().orElse(0) == 0; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -206,7 +276,7 @@ public String toString() { } /** - * Builder for the UAttributes object. + * Builder for easy construction of the UAttributes object. */ public static class UAttributesBuilder { @@ -220,6 +290,12 @@ public static class UAttributesBuilder { private Integer commstatus; private UUID reqid; + /** + * Construct the UAttributesBuilder with the configurations that are required for every payload transport. + * @param id Unique identifier for the message. + * @param type Message type such as Publish a state change, RPC request or RPC response. + * @param priority uProtocol Prioritization classifications. + */ public UAttributesBuilder(UUID id, UMessageType type, UPriority priority) { this.id = id; this. type = type; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java index ae47ffaa..48b708b6 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java @@ -24,6 +24,9 @@ import java.util.Arrays; import java.util.Optional; +/** + * uProtocol defines message types. Using the message type, validation can be performed to ensure transport validity of the data in the {@link UAttributes}. + */ public enum UMessageType { PUBLISH(0, "pub.v1"), // Publish or notification event REQUEST(1, "req.v1"), // Request @@ -47,8 +50,8 @@ public String stringValue() { /** * Find the Message type from a numeric value. Mind you, it might not exist. - * @param value numeric message type . - * @return Returns the UMessageType matching the numeric value + * @param value numeric message type. + * @return Returns the UMessageType matching the numeric value. */ public static Optional from(int value) { return Arrays.stream(UMessageType.values()) @@ -58,8 +61,8 @@ public static Optional from(int value) { /** * Find the Message type from a string value. Mind you, it might not exist. - * @param value string message type . - * @return Returns the UMessageType matching the string value + * @param value string message type. + * @return Returns the UMessageType matching the string value. */ public static Optional from(String value) { return Arrays.stream(UMessageType.values()) diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index 1069d419..8ce3d088 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -32,7 +32,7 @@ import java.util.UUID; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; public class UAttributeTest { @@ -92,6 +92,12 @@ public void testCreatingUattributes() { assertEquals(id, uAttributes.id()); assertEquals(UMessageType.RESPONSE, uAttributes.type()); assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.ttl().isPresent()); + assertTrue(uAttributes.token().isPresent()); + assertTrue(uAttributes.sink().isPresent()); + assertTrue(uAttributes.plevel().isPresent()); + assertTrue(uAttributes.commstatus().isPresent()); + assertTrue(uAttributes.reqid().isPresent()); assertEquals(sink, uAttributes.sink().orElse(UUri.empty())); assertEquals(1000, uAttributes.ttl().orElse(0)); assertEquals(1, uAttributes.plevel().orElse(3)); @@ -100,4 +106,331 @@ public void testCreatingUattributes() { assertEquals(requestId, uAttributes.reqid().orElse(UUID.randomUUID())); } + @Test + @DisplayName("Test creating a basic UAttributes, only required values") + public void test_basic_uattribues_only_required_values() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.LOW) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.PUBLISH, uAttributes.type()); + assertEquals(UPriority.LOW, uAttributes.priority()); + assertTrue(uAttributes.ttl().isEmpty()); + assertTrue(uAttributes.token().isEmpty()); + assertTrue(uAttributes.sink().isEmpty()); + assertTrue(uAttributes.plevel().isEmpty()); + assertTrue(uAttributes.commstatus().isEmpty()); + assertTrue(uAttributes.reqid().isEmpty()); + + } + + @Test + @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC request") + public void test_create_uattributes_builder_for_basic_rpc_request() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UAttributes uAttributes = UAttributes.forRpcRequest(id, sink) + .withToken("someToken") + .withTtl(10000) + .build(); + assertTrue(uAttributes.isRpcRequest()); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.REQUEST, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertEquals(sink, uAttributes.sink().orElse(UUri.empty())); + assertEquals("someToken", uAttributes.token().orElse("")); + assertEquals(10000, uAttributes.ttl().orElse(0)); + } + + @Test + @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC request with values") + public void test_create_uattributes_builder_for_basic_rpc_request_with_values() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = UAttributes.forRpcRequest(id, UAuthority.local(), UEntity.fromName("body.access"), "ExecuteWindowCommand") + .withToken("someToken") + .withTtl(10000) + .build(); + assertTrue(uAttributes.isRpcRequest()); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.REQUEST, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertEquals("body.access", uAttributes.sink().orElse(UUri.empty()).uEntity().name()); + assertEquals("someToken", uAttributes.token().orElse("")); + assertEquals(10000, uAttributes.ttl().orElse(0)); + } + + @Test + @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC response") + public void test_create_uattributes_builder_for_basic_rpc_response() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UUID requestId = UUID.randomUUID(); + final UAttributes uAttributes = UAttributes.forRpcResponse(id, sink, requestId) + .withToken("someToken") + .withTtl(10000) + .build(); + assertTrue(uAttributes.isRpcResponse()); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertEquals("petapp.ultifi.gm.com", uAttributes.sink().orElse(UUri.empty()).uEntity().name()); + assertEquals("someToken", uAttributes.token().orElse("")); + assertEquals(10000, uAttributes.ttl().orElse(0)); + } + + @Test + @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC response with values") + public void test_create_uattributes_builder_for_basic_rpc_response_with_values() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUID requestId = UUID.randomUUID(); + final UAttributes uAttributes = UAttributes.forRpcResponse(id, UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), requestId) + .withToken("someToken") + .withTtl(10000) + .build(); + assertTrue(uAttributes.isRpcResponse()); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertEquals("petapp.ultifi.gm.com", uAttributes.sink().orElse(UUri.empty()).uEntity().name()); + assertEquals("someToken", uAttributes.token().orElse("")); + assertEquals(10000, uAttributes.ttl().orElse(0)); + } + + @Test + @DisplayName("Test creating UAttributes with null required attribute id") + public void test_create_uattributes_missing_required_attribute_id() { + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(null, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .build(); + assertNull(uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + } + + @Test + @DisplayName("Test creating UAttributes with null required attribute type") + public void test_create_uattributes_missing_required_attribute_type() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + null, UPriority.REALTIME_INTERACTIVE) + .build(); + assertEquals(id, uAttributes.id()); + assertNull(uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + } + + @Test + @DisplayName("Test creating UAttributes with null required attribute type priority") + public void test_create_uattributes_missing_required_attribute_priority() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.REQUEST, null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.REQUEST, uAttributes.type()); + assertNull(uAttributes.priority()); + } + + @Test + @DisplayName("Test creating UAttribues with a null ttl") + public void test_create_uattributes_with_null_ttl() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withTtl(null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.ttl().isEmpty()); + + } + + @Test + @DisplayName("Test creating UAttribues with a null or blank token") + public void test_create_uattributes_with_null_or_blank_token() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withToken(null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.token().isEmpty()); + + final UAttributes uAttributes2 = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withToken(" ") + .build(); + assertEquals(id, uAttributes2.id()); + assertEquals(UMessageType.RESPONSE, uAttributes2.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes2.priority()); + assertTrue(uAttributes2.token().isEmpty()); + } + + @Test + @DisplayName("Test creating UAttribues with a null sink") + public void test_create_uattributes_with_null_sink() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.sink().isEmpty()); + } + + @Test + @DisplayName("Test creating UAttribues with a null permission level") + public void test_create_uattributes_with_null_permission_level() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withPermissionLevel(null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.plevel().isEmpty()); + } + + @Test + @DisplayName("Test creating UAttribues with a null communication status") + public void test_create_uattributes_with_null_comm_status() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withCommStatus(null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.commstatus().isEmpty()); + } + + @Test + @DisplayName("Test creating UAttribues with a null request id") + public void test_create_uattributes_with_null_request_id() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withReqId(null) + .build(); + assertEquals(id, uAttributes.id()); + assertEquals(UMessageType.RESPONSE, uAttributes.type()); + assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); + assertTrue(uAttributes.commstatus().isEmpty()); + } + + @Test + @DisplayName("Test is this UAttributes configured for an RPC request payload") + public void test_is_uattributes_configured_for_rpc_request_payload() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .build(); + assertTrue(uAttributes.isRpcRequest()); + } + + @Test + @DisplayName("Test scenarios for UAttributes not configured for an RPC request payload") + public void test_scenarios_for_uattributes_not_configured_for_rpc_request_payload() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final String vin = "someVin"; + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", vin)), + UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .build(); + assertFalse(uAttributesNoSink.isRpcRequest()); + + final UAttributes uAttributesWrongType = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .build(); + assertFalse(uAttributesWrongType.isRpcRequest()); + } + + @Test + @DisplayName("Test is this UAttributes configured for an RPC response payload") + public void test_is_uattributes_configured_for_rpc_response_payload() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUID requestId = UUID.randomUUID(); + final UUri sink = new UUri(UAuthority.remote("azure", "bo.ultifi.gm.com"), + new UEntity("petapp.ultifi.gm.com","1"), UResource.empty()); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(requestId) + .build(); + assertTrue(uAttributes.isRpcResponse()); + } + + @Test + @DisplayName("Test scenarios for UAttributes not configured for an RPC response payload") + public void test_scenarios_for_uattributes_not_configured_for_rpc_response_payload() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UUID requestId = UUID.randomUUID(); + final UUri sink = new UUri(UAuthority.remote("azure", "bo.ultifi.gm.com"), + new UEntity("petapp.ultifi.gm.com","1"), UResource.empty()); + final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withReqId(requestId) + .build(); + assertFalse(uAttributesNoSink.isRpcResponse()); + + final UAttributes uAttributesWrongType = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(requestId) + .build(); + assertFalse(uAttributesWrongType.isRpcResponse()); + + final UAttributes uAttributesNoRequestId = new UAttributes.UAttributesBuilder(id, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .build(); + assertFalse(uAttributesNoRequestId.isRpcResponse()); + + final UAttributes simplePublish = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .build(); + assertFalse(simplePublish.isRpcResponse()); + } + + @Test + @DisplayName("Test is this UAttributes configured for payload where there was no platform error") + public void test_is_uattributes_configured_for_payload_with_no_platform_error() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .build(); + assertTrue(uAttributes.isPlatformTransportSuccess()); + + final UAttributes alsoOK = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .withCommStatus(0) + .build(); + assertTrue(alsoOK.isPlatformTransportSuccess()); + } + + @Test + @DisplayName("Test is this UAttributes configured for payload where there was a platform error") + public void test_is_uattributes_configured_for_payload_with_platform_error() { + final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .withCommStatus(3) + .build(); + assertFalse(uAttributes.isPlatformTransportSuccess()); + } + } From 70df16ebf22f2a374973bf6c8be531aa4750a879 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Sun, 10 Sep 2023 14:15:50 +0300 Subject: [PATCH 21/52] adding tests for UPriority and UMessageType --- .../datamodel/UMessageTypeTest.java | 50 +++++++++++++ .../utransport/datamodel/UPriorityTest.java | 73 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java new file mode 100644 index 00000000..78974313 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java @@ -0,0 +1,50 @@ +package org.eclipse.uprotocol.utransport.datamodel; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class UMessageTypeTest { + + @Test + @DisplayName("Test finding UMessageType from a numeric value") + public void test_find_UMessageType_from_number() { + assertTrue(UMessageType.from(0).isPresent()); + assertEquals(UMessageType.PUBLISH, UMessageType.from(0).get()); + + assertTrue(UMessageType.from(1).isPresent()); + assertEquals(UMessageType.REQUEST, UMessageType.from(1).get()); + + assertTrue(UMessageType.from(2).isPresent()); + assertEquals(UMessageType.RESPONSE, UMessageType.from(2).get()); + + } + + @Test + @DisplayName("Test finding UMessageType from a numeric value that does not exist") + public void test_find_UMessageType_from_number_that_does_not_exist() { + assertTrue(UMessageType.from(-42).isEmpty()); + } + + @Test + @DisplayName("Test finding UMessageType from a string value") + public void test_find_UMessageType_from_string() { + assertTrue(UMessageType.from("pub.v1").isPresent()); + assertEquals(UMessageType.PUBLISH, UMessageType.from("pub.v1").get()); + + assertTrue(UMessageType.from("req.v1").isPresent()); + assertEquals(UMessageType.REQUEST, UMessageType.from("req.v1").get()); + + assertTrue(UMessageType.from("res.v1").isPresent()); + assertEquals(UMessageType.RESPONSE, UMessageType.from("res.v1").get()); + + } + + @Test + @DisplayName("Test finding UMessageType from a numeric string that does not exist") + public void test_find_UMessageType_from_string_that_does_not_exist() { + assertTrue(UMessageType.from("BOOM").isEmpty()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java new file mode 100644 index 00000000..5dd95f3a --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java @@ -0,0 +1,73 @@ +package org.eclipse.uprotocol.utransport.datamodel; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class UPriorityTest { + + @Test + @DisplayName("Test finding UPriority from a numeric value") + public void test_find_upriority_from_number() { + assertTrue(UPriority.from(0).isPresent()); + assertEquals(UPriority.LOW, UPriority.from(0).get()); + + assertTrue(UPriority.from(1).isPresent()); + assertEquals(UPriority.STANDARD, UPriority.from(1).get()); + + assertTrue(UPriority.from(2).isPresent()); + assertEquals(UPriority.OPERATIONS, UPriority.from(2).get()); + + assertTrue(UPriority.from(3).isPresent()); + assertEquals(UPriority.MULTIMEDIA_STREAMING, UPriority.from(3).get()); + + assertTrue(UPriority.from(4).isPresent()); + assertEquals(UPriority.REALTIME_INTERACTIVE, UPriority.from(4).get()); + + assertTrue(UPriority.from(5).isPresent()); + assertEquals(UPriority.SIGNALING, UPriority.from(5).get()); + + assertTrue(UPriority.from(6).isPresent()); + assertEquals(UPriority.NETWORK_CONTROL, UPriority.from(6).get()); + } + + @Test + @DisplayName("Test finding UPriority from a numeric value that does not exist") + public void test_find_upriority_from_number_that_does_not_exist() { + assertTrue(UPriority.from(-42).isEmpty()); + } + + @Test + @DisplayName("Test finding UPriority from a string value") + public void test_find_upriority_from_string() { + assertTrue(UPriority.from("CS0").isPresent()); + assertEquals(UPriority.LOW, UPriority.from("CS0").get()); + + assertTrue(UPriority.from("CS1").isPresent()); + assertEquals(UPriority.STANDARD, UPriority.from("CS1").get()); + + assertTrue(UPriority.from("CS2").isPresent()); + assertEquals(UPriority.OPERATIONS, UPriority.from("CS2").get()); + + assertTrue(UPriority.from("CS3").isPresent()); + assertEquals(UPriority.MULTIMEDIA_STREAMING, UPriority.from("CS3").get()); + + assertTrue(UPriority.from("CS4").isPresent()); + assertEquals(UPriority.REALTIME_INTERACTIVE, UPriority.from("CS4").get()); + + assertTrue(UPriority.from("CS5").isPresent()); + assertEquals(UPriority.SIGNALING, UPriority.from("CS5").get()); + + assertTrue(UPriority.from("CS6").isPresent()); + assertEquals(UPriority.NETWORK_CONTROL, UPriority.from("CS6").get()); + } + + @Test + @DisplayName("Test finding UPriority from a numeric string that does not exist") + public void test_find_upriority_from_string_that_does_not_exist() { + assertTrue(UPriority.from("BOOM").isEmpty()); + } + +} \ No newline at end of file From 393c0b517d26a24de81f86203490eeac0bbb5886 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Sun, 10 Sep 2023 14:24:06 +0300 Subject: [PATCH 22/52] adding tests for USerializationHint --- .../datamodel/USerializationHintTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java new file mode 100644 index 00000000..7a08036e --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java @@ -0,0 +1,63 @@ +package org.eclipse.uprotocol.utransport.datamodel; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class USerializationHintTest { + + @Test + @DisplayName("Test finding USerializationHint from a numeric value") + public void test_find_USerializationHint_from_number() { + assertTrue(USerializationHint.from(0).isPresent()); + assertEquals(USerializationHint.UNKNOWN, USerializationHint.from(0).get()); + + assertTrue(USerializationHint.from(1).isPresent()); + assertEquals(USerializationHint.PROTOBUF, USerializationHint.from(1).get()); + + assertTrue(USerializationHint.from(2).isPresent()); + assertEquals(USerializationHint.JSON, USerializationHint.from(2).get()); + + assertTrue(USerializationHint.from(3).isPresent()); + assertEquals(USerializationHint.SOMEIP, USerializationHint.from(3).get()); + + assertTrue(USerializationHint.from(4).isPresent()); + assertEquals(USerializationHint.RAW, USerializationHint.from(4).get()); + + } + + @Test + @DisplayName("Test finding USerializationHint from a numeric value that does not exist") + public void test_find_USerializationHint_from_number_that_does_not_exist() { + assertTrue(USerializationHint.from(-42).isEmpty()); + } + + @Test + @DisplayName("Test finding USerializationHint from a string value") + public void test_find_USerializationHint_from_string() { + assertTrue(USerializationHint.from("").isPresent()); + assertEquals(USerializationHint.UNKNOWN, USerializationHint.from("").get()); + + assertTrue(USerializationHint.from("application/x-protobuf").isPresent()); + assertEquals(USerializationHint.PROTOBUF, USerializationHint.from("application/x-protobuf").get()); + + assertTrue(USerializationHint.from("application/json").isPresent()); + assertEquals(USerializationHint.JSON, USerializationHint.from("application/json").get()); + + assertTrue(USerializationHint.from("application/x-someip").isPresent()); + assertEquals(USerializationHint.SOMEIP, USerializationHint.from("application/x-someip").get()); + + assertTrue(USerializationHint.from("application/octet-stream").isPresent()); + assertEquals(USerializationHint.RAW, USerializationHint.from("application/octet-stream").get()); + + } + + @Test + @DisplayName("Test finding USerializationHint from a numeric string that does not exist") + public void test_find_USerializationHint_from_string_that_does_not_exist() { + assertTrue(USerializationHint.from("BOOM").isEmpty()); + } + +} \ No newline at end of file From cfec8395e3dd78d2ac4578c0b241c79bc1820402 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Sun, 10 Sep 2023 19:26:03 +0300 Subject: [PATCH 23/52] working on UAttributesValidator and UAttributesValidatorTest --- .../utransport/datamodel/UAttributes.java | 3 + .../validate/UAttributesValidator.java | 277 +++---- .../validator/UAttributesValidatorTest.java | 694 +++++++++++++++++- 3 files changed, 824 insertions(+), 150 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 0ad3e250..307f86f3 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -34,6 +34,9 @@ * When sending data over uTransport the basic API for send uses a source topic and the UPayload as the data. * Any other information about the message is placed in the UAttributes class. * The UAttributes class holds the additional information along with business methods for understanding more about the actual message sent. + * {@link UAttributes} is the class that defines the Payload. It is the place for configuring time to live, priority, security tokens and more. + * Each UAttributes class defines a different type of message payload. The payload can represent a simple published payload with some state change, + * Payload representing an RPC request or Payload representing an RPC response. */ public class UAttributes { diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java index fce3b6f0..4e8f7cca 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java @@ -20,28 +20,33 @@ */ package org.eclipse.uprotocol.utransport.validate; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; +import org.eclipse.uprotocol.utransport.datamodel.UPriority; import org.eclipse.uprotocol.utransport.datamodel.UStatus; -import org.eclipse.uprotocol.uuid.factory.UUIDUtils; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; +import org.eclipse.uprotocol.uuid.factory.UUIDUtils; + +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** - * Abstract class for validating UAttributes. - * - * UPriority is not validated since it cannot be anything other than a valid UPriority. - * - * + * {@link UAttributes} is the class that defines the Payload. It is the place for configuring time to live, priority, security tokens and more. + * Each UAttributes class defines a different type of message payload. The payload can represent a simple published payload with some state change, + * Payload representing an RPC request or Payload representing an RPC response. + * UAttributesValidator is a base class for all UAttribute validators, that can help validate that the {@link UAttributes} object is correctly defined + * to define the Payload correctly. */ public abstract class UAttributesValidator { - + + /** + * Static factory method for getting a validator according to the {@link UMessageType} defined in the {@link UAttributes}. + * @param attribute UAttributes containing the UMessageType. + * @return returns a UAttributesValidator according to the {@link UMessageType} defined in the {@link UAttributes}. + */ public static UAttributesValidator getValidator(UAttributes attribute) { if (attribute.type() == null) { return Validators.PUBLISH.validator(); @@ -57,9 +62,9 @@ public static UAttributesValidator getValidator(UAttributes attribute) { } - /** - * Enum that hold the implementations of uattributesValidator according to type. + * Validators Factory. Example: + * UAttributesValidator validateForPublishMessageType = UAttributesValidator.Validators.PUBLISH.validator() */ public enum Validators { PUBLISH (new Publish()), @@ -78,13 +83,20 @@ public UAttributesValidator validator() { } + /** + * Take a {@link UAttributes} object and run validations. + * @param attributes The UAttriubes to validate. + * @return Returns a {@link UStatus} that is success or failed with a message containing all validation errors for + * invalid configurations. + */ public UStatus validate(UAttributes attributes) { - final String errorMessage = Stream.of(validateType(attributes), - validateId(attributes), - validateSink(attributes), + final String errorMessage = Stream.of( + validateId(attributes), + validateType(attributes), validatePriority(attributes), - validateCommStatus(attributes), validateTtl(attributes), + validateSink(attributes), + validateCommStatus(attributes), validatePermissionLevel(attributes), validateReqId(attributes)) .filter(UStatus::isFailed) @@ -94,97 +106,120 @@ public UStatus validate(UAttributes attributes) { UStatus.failed(errorMessage, Code.INVALID_ARGUMENT); } + /** + * Indication if the Payload with these UAttributes is expired. + * @param uAttributes UAttributes with time to live value. + * @return Returns a {@link UStatus} that is success meaning not expired or failed with a validation message or expiration. + */ + public UStatus isExpired(UAttributes uAttributes) { + try { + final Optional maybeTtl = uAttributes.ttl(); + if (maybeTtl.isEmpty()) { + return UStatus.ok("Not Expired"); + } + int ttl = maybeTtl.get(); + if (ttl <= 0) { + return UStatus.ok("Not Expired"); + } - public UStatus validatePriority(UAttributes attributes) { - return attributes.priority() != null ? UStatus.ok() : - UStatus.failed("Invalid Priority", Code.INVALID_ARGUMENT.value()); - } + long delta = System.currentTimeMillis() - UUIDUtils.getTime(uAttributes.id()); - public UStatus validateTtl(UAttributes attributes) { - Optional ttl = attributes.ttl(); - if (ttl.isPresent()) { - return ttl.get() > 0 ? UStatus.ok() : - UStatus.failed("Invalid TTL", Code.INVALID_ARGUMENT.value()); + return delta >= ttl ? UStatus.failed("Payload is expired", Code.DEADLINE_EXCEEDED) : UStatus.ok("Not Expired"); + } catch (Exception e) { + return UStatus.ok("Not Expired"); } - return UStatus.ok(); } + /** + * Validate the id attribute, it is required. + * @param attributes UAttributes object containing the id to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. + */ public UStatus validateId(UAttributes attributes) { + final UUID id = attributes.id(); try { - return UUIDUtils.isUuid(attributes.id()) ? UStatus.ok() : - UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); + return UUIDUtils.isUuid(id) ? UStatus.ok() : + UStatus.failed(String.format("Invalid UUID [%s]", id), Code.INVALID_ARGUMENT.value()); } catch (Exception e) { - return UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); + return UStatus.failed(String.format("Invalid UUID [%s] [%s]", id, e.getMessage()), Code.INVALID_ARGUMENT.value()); } } /** - * Validate the sink Uri for the default case. - * @param attributes UAttributes to validate - * @return Returns a UStatus indicating if the Uri is valid or not. + * Validate the {@link UPriority} since it is required. + * @param attributes UAttributes object containing the message priority to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ - public UStatus validateSink(UAttributes attributes) { - Optional sink = attributes.sink(); - if (sink.isPresent()) { - return UriValidator.validate(attributes.sink().get()); - } - return UStatus.ok(); + public UStatus validatePriority(UAttributes attributes) { + return attributes.priority() == null ? + UStatus.failed("Priority is missing", Code.INVALID_ARGUMENT.value()) : UStatus.ok(); } /** - * Validate the commStatus for the default case. - * @param attributes UAttributes to validate - * @return Returns a UStatus indicating if the commStatus is valid or not. + * Validate the time to live configuration. If the UAttributes does not contain a time to live then the UStatus is ok. + * @param attributes UAttributes object containing the message time to live configuration to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ - public UStatus validateCommStatus(UAttributes attributes) { - Optional commStatus = attributes.commstatus(); + public UStatus validateTtl(UAttributes attributes) { + return attributes.ttl() + .filter(ttl -> ttl <= 0) + .map(ttl -> UStatus.failed(String.format("Invalid TTL [%s]", ttl), Code.INVALID_ARGUMENT.value())) + .orElse(UStatus.ok()); + } - if (commStatus.isPresent()) { - Optional code = Code.from(commStatus.get()); - return code.isPresent() ? UStatus.ok() : - UStatus.failed("Invalid Communication Status Code", Code.INVALID_ARGUMENT.value()); - } - return UStatus.ok(); + /** + * Validate the sink Uri for the default case. If the UAttributes does not contain a sink then the UStatus is ok. + * @param attributes UAttributes object containing the sink to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. + */ + public UStatus validateSink(UAttributes attributes) { + return attributes.sink() + .map(UriValidator::validate) + .orElse(UStatus.ok()); } /** - * Validate the permissionLevel for the default case. - * @param attributes UAttributes to validate + * Validate the permissionLevel for the default case. If the UAttributes does not contain a permission level then the UStatus is ok. + * @param attributes UAttributes object containing the permission level to validate. * @return Returns a UStatus indicating if the permissionLevel is valid or not. */ public UStatus validatePermissionLevel(UAttributes attributes) { - final Optional plevel = attributes.plevel(); - if (plevel.isPresent()) { - return plevel.get() >= 0 ? UStatus.ok() : - UStatus.failed("Invalid Permission Level", Code.INVALID_ARGUMENT.value()); - } - return UStatus.ok(); + return attributes.plevel() + .map(permissionLevel -> permissionLevel > 0 ? UStatus.ok() : UStatus.failed("Invalid Permission Level", Code.INVALID_ARGUMENT.value())) + .orElse(UStatus.ok()); + } + + /** + * Validate the commStatus for the default case. If the UAttributes does not contain a comm status then the UStatus is ok. + * @param attributes UAttributes object containing the comm status to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. + */ + public UStatus validateCommStatus(UAttributes attributes) { + return attributes.commstatus().or(() -> Optional.of(Code.OK.value())) + .flatMap(Code::from) + .map(code -> UStatus.ok()) + .orElse(UStatus.failed("Invalid Communication Status Code", Code.INVALID_ARGUMENT.value())); } /** - * Validate the correlationId for the default case. - * @param attributes UAttributes to validate - * @return Returns a UStatus indicating if the correlationId is valid or not. + * Validate the correlationId for the default case. If the UAttributes does not contain a request id then the UStatus is ok. + * @param attributes Attributes object containing the request id to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ public UStatus validateReqId(UAttributes attributes) { - final Optional correlationId = attributes.reqid(); - - if (correlationId.isPresent()) { - return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : - UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); - } - return UStatus.ok(); + return attributes.reqid() + .filter(correlationId -> !UUIDUtils.isUuid(correlationId)) + .map(correlationId -> UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value())) + .orElse(UStatus.ok()); } - /** - * Validate the MessageType of UAttributes - * @param attributes UAttributes to validate - * @return Returns a UStatus indicating if the MessageType is valid or not. + * Validate the {@link UMessageType} attribute, it is required. + * @param attributes UAttributes object containing the message type to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ public abstract UStatus validateType(UAttributes attributes); - /** * Implements validations for UAttributes that define a message that is meant for publishing state changes. */ @@ -192,12 +227,12 @@ private static class Publish extends UAttributesValidator { /** * Validates that attributes for a message meant to publish state changes has the correct type. - * @param attributes UAttributes to validate - * @return Returns a UStatus indicating if the MessageType is of the correct type. + * @param attributes UAttributes object containing the message type to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.PUBLISH ? UStatus.ok() : + return UMessageType.PUBLISH == attributes.type() ? UStatus.ok() : UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); } @@ -214,43 +249,39 @@ private static class Request extends UAttributesValidator { /** * Validates that attributes for a message meant for an RPC request has the correct type. - * @param attributes UAttributes to validate. - * @return Returns a UStatus indicating if the MessageType is of the correct type. + * @param attributes UAttributes object containing the message type to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.REQUEST ? UStatus.ok() : - UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); + return UMessageType.REQUEST == attributes.type() ? UStatus.ok() : + UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); } /** * Validates that attributes for a message meant for an RPC request has a destination sink. - * @param attributes Attributes to validate. - * @return Returns a UStatus indicating if the Uri is valid or not. + * In the case of an RPC request, the sink is required. + * @param attributes UAttributes object containing the sink to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ @Override public UStatus validateSink(UAttributes attributes) { - final Optional sink = attributes.sink(); - - if (!sink.isPresent()) { - return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value()); - } - return UriValidator.validateRpcResponse(sink.get()); + return attributes.sink() + .map(UriValidator::validateRpcResponse) + .orElse(UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value())); } /** - * Validate the ttl. - * @param attributes - * @return Returns a UStatus indicating if the ttl is valid or not. + * Validate the time to live configuration. + * In the case of an RPC request, the time to live is required. + * @param attributes UAttributes object containing the time to live to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ @Override public UStatus validateTtl(UAttributes attributes) { - final Optional ttl = attributes.ttl(); - if (!ttl.isPresent()) { - return UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT.value()); - } else { - return ttl.get() > 0 ? UStatus.ok() : UStatus.failed("Invalid TTL", Code.INVALID_ARGUMENT.value()); - } + return attributes.ttl() + .map(ttl -> ttl > 0 ? UStatus.ok() : UStatus.failed(String.format("Invalid TTL [%s]", ttl), Code.INVALID_ARGUMENT.value())) + .orElse(UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT.value())); } @Override @@ -259,47 +290,47 @@ public String toString() { } } - /** - * Validate UAttributes with type UMessageType RESPONSE + * Implements validations for UAttributes that define a message that is meant for an RPC response. */ private static class Response extends UAttributesValidator { + /** + * Validates that attributes for a message meant for an RPC response has the correct type. + * @param attributes UAttributes object containing the message type to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. + */ @Override public UStatus validateType(UAttributes attributes) { - return attributes.type() == UMessageType.RESPONSE ? UStatus.ok() : - UStatus.failed("Invalid Type", Code.INVALID_ARGUMENT.value()); + return UMessageType.RESPONSE == attributes.type() ? UStatus.ok() : + UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); } /** - * Validate the sink Uri. - * @param attributes - * @return Returns a UStatus indicating if the Uri is valid or not. - */ + * Validates that attributes for a message meant for an RPC response has a destination sink. + * In the case of an RPC response, the sink is required. + * @param attributes UAttributes object containing the sink to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. + */ @Override public UStatus validateSink(UAttributes attributes) { - final Optional sink = attributes.sink(); - - if (!sink.isPresent()) { - return UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value()); - } - return UriValidator.validateRpcMethod(sink.get()); + return attributes.sink() + .map(UriValidator::validateRpcMethod) + .orElse(UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value())); } + /** - * Validate the correlationId for the default case. - * @param attributes - * @return Returns a UStatus indicating if the correlationId is valid or not. + * Validate the correlationId. n the case of an RPC response, the correlation id is required. + * @param attributes UAttributes object containing the correlation id to validate. + * @return Returns a {@link UStatus} that is success or failed with a failure message. */ @Override public UStatus validateReqId(UAttributes attributes) { - final Optional correlationId = attributes.reqid(); - - if (!correlationId.isPresent()) { - return UStatus.failed("Missing correlationId", Code.INVALID_ARGUMENT.value()); - } - return UUIDUtils.isUuid(correlationId.get()) ? UStatus.ok() : - UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value()); + return attributes.reqid() + .map(correlationId -> UUIDUtils.isUuid(correlationId) ? + UStatus.ok() : UStatus.failed(String.format("Invalid correlationId [%s]", correlationId), Code.INVALID_ARGUMENT.value())) + .orElse(UStatus.failed("Missing correlationId", Code.INVALID_ARGUMENT.value())); } @Override diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index 1e9dcede..784f3e70 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -21,6 +21,9 @@ package org.eclipse.uprotocol.utransport.validator; +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.factory.UriFactory; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; @@ -53,27 +56,648 @@ public void test_fetching_validator_for_valid_types() { UAttributesValidator request = UAttributesValidator.getValidator( new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), - UMessageType.REQUEST, UPriority.LOW).build()); + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE).build()); assertEquals("UAttributesValidator.Request", request.toString()); UAttributesValidator response = UAttributesValidator.getValidator( new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), - UMessageType.RESPONSE, UPriority.LOW).build()); + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE).build()); assertEquals("UAttributesValidator.Response", response.toString()); } @Test - @DisplayName("test validating_valid_publish_messagetypes") - public void test_validating_valid_publish_messagetypes() { + @DisplayName("test fetching validator when message type is null") + public void test_fetching_validator_when_message_type_is_null() { + + UAttributesValidator publish = UAttributesValidator.getValidator( + new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + null, UPriority.LOW).build()); + assertEquals("UAttributesValidator.Publish", publish.toString()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published") + public void test_validate_uAttributes_for_publish_message_payload() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals("ok", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with all values") + public void test_validate_uAttributes_for_publish_message_payload_all_values() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(1000) + .withSink(new UUri(UAuthority.local(), UEntity.fromName("body.access"), new UResource("door", "front_left", "Door"))) + .withPermissionLevel(2) + .withCommStatus(3) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals("ok", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid id") + public void test_validate_uAttributes_for_publish_message_payload_invalid_id() { + final UAttributes attributes = new UAttributesBuilder(null, UMessageType.PUBLISH, UPriority.LOW).build(); - final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid type") + public void test_validate_uAttributes_for_publish_message_payload_invalid_type() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.LOW).build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Wrong Attribute Type [RESPONSE]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid priority") + public void test_validate_uAttributes_for_publish_message_payload_invalid_priority() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, null).build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Priority is missing", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid time to live") + public void test_validate_uAttributes_for_publish_message_payload_invalid_ttl() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(-1) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid TTL [-1]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid sink") + public void test_validate_uAttributes_for_publish_message_payload_invalid_sink() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withSink(new UUri(UAuthority.local(), UEntity.empty(), UResource.empty())) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Uri is empty.", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid permission level") + public void test_validate_uAttributes_for_publish_message_payload_invalid_permission_level() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withPermissionLevel(-42) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid Permission Level", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid communication status") + public void test_validate_uAttributes_for_publish_message_payload_invalid_communication_status() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withCommStatus(-42) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid Communication Status Code", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid request id") + public void test_validate_uAttributes_for_publish_message_payload_invalid_request_id() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withReqId(UUID.randomUUID()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid UUID", status.msg()); + } + + // ---- + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request") + public void test_validate_uAttributes_for_rpc_request_message_payload() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals("ok", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with all values") + public void test_validate_uAttributes_for_rpc_request_message_payload_all_values() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .withPermissionLevel(2) + .withCommStatus(3) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals("ok", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid id") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(null, + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid type") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_type() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Wrong Attribute Type [RESPONSE]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid priority") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_priority() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, null) + .withSink(sink) + .withTtl(1000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Priority is missing", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with missing time to live") + public void test_validate_uAttributes_for_rpc_request_message_payload_missing_ttl() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Missing TTL", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid time to live") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ttl() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(-1) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid TTL [-1]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with missing sink and missing ttl") + public void test_validate_uAttributes_for_rpc_request_message_payload_missing_sink_and_missing_ttl() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Missing TTL,Missing Sink", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid sink") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_sink() { + final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid RPC response type.", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid permission level") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_permission_level() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .withPermissionLevel(-42) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid Permission Level", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid communication status") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_communication_status() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .withCommStatus(-42) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid Communication Status Code", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid request id") + public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_request_id() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withTtl(1000) + .withReqId(UUID.randomUUID()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid UUID", status.msg()); + } + + // ---- + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response") + public void test_validate_uAttributes_for_rpc_response_message_payload() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals("ok", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with all values") + public void test_validate_uAttributes_for_rpc_response_message_payload_all_values() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPermissionLevel(2) + .withCommStatus(3) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isSuccess()); + assertEquals("ok", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid id") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_id() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(null, + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid type") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_type() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Wrong Attribute Type [PUBLISH]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid priority") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_priority() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, null) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Priority is missing", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid time to live") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_ttl() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withTtl(-1) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid TTL [-1]", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with missing sink and missing request id") + public void test_validate_uAttributes_for_rpc_response_message_payload_missing_sink_and_missing_requestId() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Missing Sink,Missing correlationId", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid sink") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_sink() { + final UUri sink = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpc("ExecuteWindowCommand")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid permission level") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_permission_level() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withPermissionLevel(-42) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid Permission Level", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid communication status") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_communication_status() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) + .withCommStatus(-42) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Invalid Communication Status Code", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with missing request id") + public void test_validate_uAttributes_for_rpc_response_message_payload_missing_request_id() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals("Missing correlationId", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid request id") + public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_request_id() { + final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + final UUID reqid = UUID.randomUUID(); + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) + .withSink(sink) + .withReqId(reqid) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); + final UStatus status = validator.validate(attributes); + assertTrue(status.isFailed()); + assertEquals(String.format("Invalid correlationId [%s]", reqid), status.msg()); + } + + // ---- + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published not expired") + public void test_validate_uAttributes_for_publish_message_payload_not_expired() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.isExpired(attributes); assertTrue(status.isSuccess()); - assertEquals(status.msg(), "ok"); + assertEquals("Not Expired", status.msg()); } + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published not expired with ttl zero") + public void test_validate_uAttributes_for_publish_message_payload_not_expired_with_ttl_zero() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(0) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.isExpired(attributes); + assertTrue(status.isSuccess()); + assertEquals("Not Expired", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published not expired with ttl") + public void test_validate_uAttributes_for_publish_message_payload_not_expired_with_ttl() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(10000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.isExpired(attributes); + assertTrue(status.isSuccess()); + assertEquals("Not Expired", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published expired with ttl") + public void test_validate_uAttributes_for_publish_message_payload_expired_with_ttl() throws InterruptedException { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(1) + .build(); + + Thread.sleep(800); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.isExpired(attributes); + assertTrue(status.isFailed()); + assertEquals("Payload is expired", status.msg()); + } + + @Test + @DisplayName("Validate a UAttributes for payload that is meant to be published not expired cant calculate bad UUID") + public void test_validate_uAttributes_for_publish_message_payload_not_expired_cant_calculate_bad_uuid() { + final UAttributes attributes = new UAttributesBuilder(UUID.randomUUID(), + UMessageType.PUBLISH, UPriority.LOW) + .withTtl(10000) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.isExpired(attributes); + assertTrue(status.isSuccess()); + assertEquals("Not Expired", status.msg()); + } + + // ---- @Test @DisplayName("test validating publish invalid ttl attribute") @@ -87,7 +711,7 @@ public void test_validating_publish_invalid_ttl_attribute() { final UStatus status = validator.validateTtl(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid TTL"); + assertEquals("Invalid TTL [-1]", status.msg()); } @Test @@ -100,7 +724,7 @@ public void test_validating_valid_ttl_attribute() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateTtl(attributes); - assertEquals(status, UStatus.ok()); + assertEquals(UStatus.ok(), status); } @Test @@ -117,12 +741,12 @@ public void test_validating_invalid_id_attribute() { UStatus status = validator.validateId(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid UUID"); + assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); UStatus status1 = validator.validateId(attributes1); assertTrue(status1.isFailed()); assertEquals(status1.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status1.msg(), "Invalid UUID"); + assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); } @Test @@ -133,7 +757,7 @@ public void test_validating_valid_id_attribute() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateId(attributes); - assertEquals(status, UStatus.ok()); + assertEquals(UStatus.ok(), status); } @Test @@ -148,7 +772,7 @@ public void test_validating_invalid_sink_attribute() { assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Uri is empty."); + assertEquals("Uri is empty.", status.msg()); } @Test @@ -160,7 +784,7 @@ public void test_validating_valid_sink_attribute() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateSink(attributes); - assertEquals(status, UStatus.ok()); + assertEquals(UStatus.ok(), status); } @Test @@ -174,7 +798,7 @@ public void test_validating_invalid_ReqId_attribute() { final UStatus status = validator.validateReqId(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid UUID"); + assertEquals("Invalid UUID", status.msg()); } @Test @@ -188,7 +812,7 @@ public void test_validating_valid_ReqId_attribute() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateReqId(attributes); - assertEquals(status, UStatus.ok()); + assertEquals(UStatus.ok(), status); } @@ -205,12 +829,25 @@ public void test_validating_invalid_PermissionLevel_attribute() { final UStatus status = validator.validatePermissionLevel(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid Permission Level"); + assertEquals("Invalid Permission Level", status.msg()); } @Test @DisplayName("test validating valid PermissionLevel attribute") public void test_validating_valid_PermissionLevel_attribute() { + final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), + UMessageType.PUBLISH, UPriority.LOW) + .withPermissionLevel(3) + .build(); + + final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); + final UStatus status = validator.validatePermissionLevel(attributes); + assertEquals(UStatus.ok(), status); + } + + @Test + @DisplayName("test validating valid PermissionLevel attribute") + public void test_validating_valid_PermissionLevel_attribute_invalid() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW) .withPermissionLevel(0) @@ -218,7 +855,9 @@ public void test_validating_valid_PermissionLevel_attribute() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validatePermissionLevel(attributes); - assertEquals(status, UStatus.ok()); + assertTrue(status.isFailed()); + assertEquals("Invalid Permission Level", status.msg()); + assertEquals(3, status.getCode()); } @Test @@ -234,7 +873,7 @@ public void test_validating_invalid_commstatus_attribute() { final UStatus status = validator.validateCommStatus(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid Communication Status Code"); + assertEquals( "Invalid Communication Status Code", status.msg()); } @Test @@ -248,7 +887,7 @@ public void test_validating_valid_commstatus_attribute() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validateCommStatus(attributes); - assertEquals(status, UStatus.ok()); + assertEquals(UStatus.ok(), status); } @@ -267,7 +906,7 @@ public void test_validating_request_message_types() { assertEquals("UAttributesValidator.Request", validator.toString()); final UStatus status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals(status.msg(), "ok"); + assertEquals("ok", status.msg()); } @Test @@ -283,7 +922,7 @@ public void test_validating_request_validator_with_wrong_messagetype() { final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Wrong Attribute Type [PUBLISH],Missing Sink,Missing TTL", status.msg()); + assertEquals("Wrong Attribute Type [PUBLISH],Missing TTL,Missing Sink", status.msg()); } @Test @@ -301,7 +940,7 @@ public void test_validating_request_validator_with_wrong_bad_ttl() { final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid TTL"); + assertEquals("Invalid TTL [-1]", status.msg()); } @Test @@ -320,14 +959,15 @@ public void test_validating_response_validator_with_wrong_bad_ttl() { final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid TTL"); + assertEquals("Invalid TTL [-1]", status.msg()); } @Test @DisplayName("test validating response validator using bad UUID") public void test_validating_response_validator_with_bad_reqid() { - final UAttributes attributes = new UAttributesBuilder(UUID.randomUUID(), + final UUID id = UUID.randomUUID(); + final UAttributes attributes = new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) .withTtl(100) @@ -339,7 +979,7 @@ public void test_validating_response_validator_with_bad_reqid() { final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(status.msg(), "Invalid UUID"); + assertEquals(String.format("Invalid UUID [%s]", id), status.msg()); } @@ -371,7 +1011,7 @@ public void test_validating_response_validator_with_wrong_messagetype() { final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid Type,Missing Sink,Missing correlationId", status.msg()); + assertEquals("Wrong Attribute Type [PUBLISH],Missing Sink,Missing correlationId", status.msg()); } @@ -387,6 +1027,6 @@ public void test_validating_request_containing_token() { final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); assertEquals("UAttributesValidator.Publish", validator.toString()); final UStatus status = validator.validate(attributes); - assertEquals(status, UStatus.ok()); + assertEquals(UStatus.ok(), status); } } From 7fdbe966552ae0995c8ae5314b2caa103b13c87b Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Mon, 11 Sep 2023 17:53:38 +0300 Subject: [PATCH 24/52] fixing error messages for uAttributesValidator --- .../utransport/validator/UAttributesValidatorTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index 784f3e70..c68b6070 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -115,7 +115,7 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_id() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + assertTrue(status.msg().contains("Invalid UUID [null]")); } @Test @@ -265,7 +265,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + assertTrue(status.msg().contains("Invalid UUID [null]")); } @Test @@ -470,7 +470,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_i final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + assertTrue(status.msg().contains("Invalid UUID [null]")); } @Test @@ -741,12 +741,12 @@ public void test_validating_invalid_id_attribute() { UStatus status = validator.validateId(attributes); assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + assertTrue(status.msg().contains("Invalid UUID [null]")); UStatus status1 = validator.validateId(attributes1); assertTrue(status1.isFailed()); assertEquals(status1.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid UUID [null] [Cannot invoke \"java.util.UUID.version()\" because \"uuid\" is null]", status.msg()); + assertTrue(status.msg().contains("Invalid UUID [null]")); } @Test From a968959ffaca348dd6c39844e269a9167daeb234 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Mon, 11 Sep 2023 16:03:09 -0400 Subject: [PATCH 25/52] Reverting the UriFormat change Also adding more business logic to UAuthority, UEntity, and UResource. --- .../uprotocol/uri/datamodel/LongUri.java | 40 ----------- .../uprotocol/uri/datamodel/MicroUri.java | 39 ---------- .../uprotocol/uri/datamodel/ShortUri.java | 38 ---------- .../uprotocol/uri/datamodel/UAuthority.java | 71 +++++++++++-------- .../uprotocol/uri/datamodel/UEntity.java | 2 +- .../uprotocol/uri/datamodel/UResource.java | 32 +++++++++ .../eclipse/uprotocol/uri/datamodel/UUri.java | 19 +---- .../uprotocol/uri/datamodel/UriFormat.java | 46 ------------ .../uprotocol/utransport/UTransport.java | 19 +++-- .../uprotocol/uri/datamodel/UUriTest.java | 17 +---- .../uprotocol/uri/factory/UriFactoryTest.java | 2 +- 11 files changed, 84 insertions(+), 241 deletions(-) delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java deleted file mode 100644 index 72eae63d..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/LongUri.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import org.eclipse.uprotocol.uri.factory.UriFactory; - -/** - * Long Format URI - */ -public class LongUri extends UriFormat { - - public LongUri(UUri uri) { - super (UriFactory.buildUProtocolUri(uri), uri); - } - - @Override - public boolean isEmpty() { - return uProtocolUri.isEmpty(); - } - -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java deleted file mode 100644 index ed08ce1d..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/MicroUri.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ -package org.eclipse.uprotocol.uri.datamodel; - -import org.eclipse.uprotocol.uri.factory.UriFactory; - -/** - * Micro Format uProtocol URI. - */ -public class MicroUri extends UriFormat{ - - public MicroUri(UUri uri) { - super(UriFactory.buildUProtocolMicroUri(uri), uri); - } - - @Override - public boolean isEmpty() { - return uProtocolUri.length == 0; - } - -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java deleted file mode 100644 index 5e517373..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/ShortUri.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import org.eclipse.uprotocol.uri.factory.UriFactory; - -public class ShortUri extends UriFormat { - - public ShortUri(UUri uri) { - super(UriFactory.buildUProtocolShortUri(uri), uri); - } - - @Override - public boolean isEmpty() { - return uProtocolUri.isEmpty(); - } - -} - diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 760e11b3..68cde826 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -34,7 +34,7 @@ * An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ public class UAuthority { - private final static UAuthority EMPTY = new UAuthority(null, null, false); + private final static UAuthority EMPTY = new UAuthority(null, null, null, false); /** * A device is a logical independent representation of a service bus in different execution environments.
@@ -54,8 +54,6 @@ public class UAuthority { */ private final boolean markedRemote; - // TODO add user information - what is this used for? make sure it is part of the domain. - /** * The device IP address. @@ -65,36 +63,14 @@ public class UAuthority { /** * Constructor. - * * @param device The device an software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). * @param domain The domain an software entity is deployed on, such as vehicle or backoffice. + * @param address The device IP address. * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. */ - private UAuthority(String device, String domain, boolean markedRemote) { + private UAuthority(String device, String domain, InetAddress address, boolean markedRemote) { this.device = device == null ? null : device.toLowerCase(); this.domain = domain == null ? null : domain.toLowerCase(); - try { - if ((device != null) && InetAddressValidator.getInstance().isValid(device)) { - this.address = InetAddress.getByName(device); - } else { - this.address = null; - } - } catch (Exception e) { - throw new IllegalArgumentException("Invalid device name: " + device, e); - } - - this.markedRemote = markedRemote; - } - - /** - * using IP Address. - * - * @param address The device IP address. - * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. - */ - private UAuthority(InetAddress address, boolean markedRemote) { - this.device = address != null ? address.getHostAddress() : null; - this.domain = null; this.address = address; this.markedRemote = markedRemote; } @@ -119,7 +95,7 @@ public static UAuthority local() { * @return returns a remote authority that contains the device and the domain. */ public static UAuthority remote(String device, String domain) { - return new UAuthority(device, domain, true); + return remote(device, domain, null); } /** @@ -127,8 +103,41 @@ public static UAuthority remote(String device, String domain) { * @param address The device an software entity is deployed on * @return returns a remote authority that contains the device and the domain. */ - public static UAuthority remote(InetAddress device) { - return new UAuthority(device, true); + public static UAuthority remote(InetAddress address) { + return remote(null, null, address); + } + + + /** + * Static factory method for creating a remote authority using device, domain, and address.
+ * @param device The device name + * @param domain The domain name + * @param address the IP address for the device + * @return returns a remote authority that contains the device and the domain. + */ + public static UAuthority remote(String device, String domain, InetAddress address) { + InetAddress addr = address; + // Try and set the address based on device name if the name is the string + // representation of an ip address + if ( (device != null) && (addr == null) ) { + try { + if ((device != null) && InetAddressValidator.getInstance().isValid(device)) { + addr = InetAddress.getByName(device); + } else { + addr = null; + } + } catch (Exception e) { + throw new IllegalArgumentException("Invalid device name: " + device, e); + } + } + + // The IP address is populated but not the device name so set the device name + // to be the string representation of the IP address + if ((addr !=null) && (device == null)) { + device = addr.getHostAddress(); + } + + return new UAuthority(device, domain, addr, true); } /** @@ -143,7 +152,7 @@ public static UAuthority empty() { * @return returns true if this authority is remote, meaning it contains a device or a domain. */ public boolean isRemote() { - return address().isPresent() || domain().isPresent() || device().isPresent(); + return domain().isPresent() || device().isPresent(); } /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 78c4e3f9..9a84415d 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -79,7 +79,7 @@ public static UEntity fromName(String name) { * @return Returns a UEntity with id but unknown name. */ public static UEntity fromId(String version, Short id) { - return new UEntity("unknown", version, id); + return new UEntity(String.valueOf(id), version, id); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 8db0bf9b..bfa1f0de 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -133,6 +133,38 @@ public static UResource forRpc(String commandName, Short id) { return new UResource("rpc", commandName, null, id); } + /** + * Static factory method for creating a UResource using a string that contains either the id or + * a name + instance + message. + * @param resourceString String that contains the UResource information. + * @return Returns a UResource object + */ + public static UResource fromString(String resourceString) { + Objects.requireNonNull(resourceString, " Resource must have a command name."); + String[] parts = resourceString.split("#"); + String nameAndInstance = parts[0]; + + // Try and fetch the resource ID if there is one (short form) + Short maybeId = null; + try { + maybeId = Short.parseShort(nameAndInstance); + } catch (NumberFormatException e) { + maybeId = null; + + } + + if (maybeId != null) { + return UResource.fromId(maybeId); + } + + String[] nameAndInstanceParts = nameAndInstance.split("\\."); + String resourceName = nameAndInstanceParts[0]; + String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; + String resourceMessage = parts.length > 1 ? parts[1] : null; + return new UResource(resourceName, resourceInstance, resourceMessage); + } + + /** * @return Returns true if this resource specifies an RPC method call. */ diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index e0ba6b56..56f88332 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -21,8 +21,6 @@ package org.eclipse.uprotocol.uri.datamodel; -import org.eclipse.uprotocol.uri.factory.UriFactory; - import java.util.Objects; import java.util.Optional; @@ -45,8 +43,6 @@ public class UUri { protected final UEntity uEntity; protected final UResource uResource; - private transient String uProtocolUri; - // Transport specific ID private transient Integer id; @@ -91,7 +87,7 @@ public boolean isEmpty() { } /** - * @return Returns the Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @return Returns the Authority represents the deployment location of a specific Software Entity. */ public UAuthority uAuthority() { return uAuthority; @@ -111,19 +107,6 @@ public UResource uResource() { return this.uResource; } - /** - * Support for a lazy generation of the uProtocol Uri string that is used in CloudEvent routing for - * sources and sinks. - * The function used to generate the string is the buildUProtocolUri method in the {@link UriFactory}. - * @return Returns the String that can be used as Source and Sink values of CloudEvents. The value is cached and only calculated on the first call. - */ - public String uProtocolUri() { - if (this.uProtocolUri == null) { - uProtocolUri = UriFactory.buildUProtocolUri(uAuthority(), uEntity(), uResource()); - } - return uProtocolUri; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java deleted file mode 100644 index 15683afc..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.eclipse.uprotocol.uri.datamodel; - -/** - * UriFormat is the interface that represents either Long, Short, or micro formats of a uProtocol Uri. - * UriFormat is passed to the transports such that a transport can fix what format they expect to use. - * - * @param The type used for the uProtocol Uri, long and short use String while micro is byte[] - */ -public abstract class UriFormat { - protected final T uProtocolUri; - private final UUri uuri; - - /** - * Constructor for UriFormat called by the child classes (Short, Long, Micro) - * @param uProtocolUri Format specific generated uProtocol URI - * @param uuri UUri data object - */ - protected UriFormat(T uProtocolUri, UUri uuri) { - this.uProtocolUri = uProtocolUri; - this.uuri = uuri; - } - - /** - * Return the uProtocol URI in the correct expected format - * @return uProtocol URI - */ - public T uProtocolUri() { - return uProtocolUri; - } - - /** - * Obtain the UUri that was used to build the Uri Format - * This method might be used if we want to convert from one format to another - * @return UUri data object - */ - public UUri uuri() { - return uuri; - } - - /** - * Check if the UProtocolUri is empty. An empty Uri means that we were not able to - * build it from the UUri. - * @return true if empty, false otherwise - */ - abstract boolean isEmpty(); -} diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java index dd5540dc..badeeb87 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java @@ -22,7 +22,7 @@ package org.eclipse.uprotocol.utransport; import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UriFormat; +import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UListener; import org.eclipse.uprotocol.utransport.datamodel.UPayload; @@ -35,7 +35,7 @@ * @param The primitive type for the UriFormat (string for long/short or byte[] for micro). */ -public interface UTransport, S> { +public interface UTransport { /** * API to register the calling uE with the underlining transport implementation. @@ -48,30 +48,27 @@ public interface UTransport, S> { /** * Transmit UPayload to the topic using the attributes defined in UTransportAttributes. - * @param The type of the UriFormat that the UTransport implementation will use. - * @param topic UriFormat of a specific type (Long, Short, or Micro) receiver of the payload. + * @param topic topic to send the payload to. * @param payload Actual payload. * @param attributes Additional transport attributes. * @return Returns an Status if managed to send to the underlying communication technology or not. */ - UStatus send(T topic, UPayload payload, UAttributes attributes); + UStatus send(UUri topic, UPayload payload, UAttributes attributes); /** * Register a method that will be called when a message comes in on the specific topic. - * @param The type of the UriFormat that the UTransport implementation will use. - * @param topic UriFormat of a specific type (Long, Short, or Micro) of the message that arrived via the underlying transport technology. + * @param topic Topic the message that arrived via the underlying transport technology. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is registered successfully. */ - UStatus registerListener(T topic, UListener listener); + UStatus registerListener(UUri topic, UListener listener); /** * Unregister a method on a topic. Messages arriving on this topic will no longer be processed by this listener. - * @param The type of the UriFormat that the UTransport implementation will use. - * @param topic UriFormat of a specific type (Long, Short, or Micro) of the messages that will no longer be processed. + * @param topic Topic the message that arrived via the underlying transport technology. * @param listener The method to execute to process the date for the topic. * @return Returns an Ack if the method is removed successfully. * */ - UStatus unregisterListener(T topic, UListener listener); + UStatus unregisterListener(UUri topic, UListener listener); } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index dcfc02b0..e146253a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -22,14 +22,13 @@ package org.eclipse.uprotocol.uri.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.Optional; - class UriTest { @Test @@ -164,20 +163,6 @@ public void test_is_empty() { assertTrue(uri2.isEmpty()); } - @Test - @DisplayName("Test lazy initialization of the uProtocol routing string") - public void test_lazy_initialization_of_uprotocol_routing_string() { - UAuthority uAuthorityRemote = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); - UUri uri = new UUri(uAuthorityRemote, use, uResource); - - assertEquals("//vcu.my_vin/body.access/1/door.front_left", uri.uProtocolUri()); - - // call it again, should not call the function, but there is not really a way to test it. - assertEquals("//vcu.my_vin/body.access/1/door.front_left", uri.uProtocolUri()); - } - @Test @DisplayName("Test getting and setting id") public void test_getting_and_setting_id() { diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java index 376cc50a..e4d3b20c 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java @@ -973,7 +973,7 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { assertEquals("front_left", Uri.uResource().instance().get()); assertTrue(Uri.uResource().message().isPresent()); assertEquals("Door", Uri.uResource().message().get()); - assertEquals(uri2, Uri.uProtocolUri()); + assertEquals(uri2, UriFactory.buildUProtocolUri(Uri)); } @Test From be60c599e61ebfb46a946314c0ad37e7abc133fe Mon Sep 17 00:00:00 2001 From: czfdcn Date: Mon, 11 Sep 2023 17:47:48 -0400 Subject: [PATCH 26/52] Adding experimental UriSerializer Serializer is to replace the UriFormat idea. This takes UUri and converts it to either a long or short form. --- .../uri/serializer/LongUriSerializer.java | 260 ++++++++++++++++++ .../uri/serializer/MicroUriSerializer.java | 190 +++++++++++++ .../uri/serializer/UriSerializer.java | 59 ++++ .../uri/serializer/UriSerializerTest.java | 24 ++ .../uri/validator/UriValidatorTest.java | 4 +- 5 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java create mode 100644 src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java create mode 100644 src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java create mode 100644 src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java new file mode 100644 index 00000000..3baf7bea --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.serializer; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import java.net.InetAddress; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * UUri Serializer that serializes a UUri to a string (long or long form) per + * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + */ +public class LongUriSerializer implements UriSerializer { + + /** + * Serialize the UUri object into a String containing either long or short form. + * + * @param Uri The URI data object. + * @return Returns the uProtocol URI string from an URI data object + * that can be used as a sink or a source in a uProtocol publish communication. + */ + @Override + public String serialize(UUri Uri) { + if (Uri == null || Uri.isEmpty()) { + return new String(); + } + + StringBuilder sb = new StringBuilder(); + + sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), false)); + + if (Uri.uAuthority().isMarkedRemote()) { + sb.append("/"); + } + + if (Uri.uEntity().isEmpty()) { + return sb.toString(); + } + + sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), false)); + + sb.append(buildResourcePartOfUri(Uri.uResource(), false)); + + return sb.toString().replaceAll("/+$", ""); + } + + + + /** + * Build a Short-Uri string from a UUri object + * + * @param Uri The URI data object. + * @return Returns the short form uProtocol URI string from an URI data object + */ + static String toShortUri(UUri Uri) { + if (Uri == null || Uri.isEmpty()) { + return new String(); + } + + StringBuilder sb = new StringBuilder(); + + sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), true)); + + if (Uri.uAuthority().isMarkedRemote()) { + sb.append("/"); + } + + if (Uri.uEntity().id().isEmpty()) { + return sb.toString(); + } + + sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), true)); + + sb.append(buildResourcePartOfUri(Uri.uResource(), true)); + + return sb.toString().replaceAll("/+$", ""); + } + + /** + * Build a Short-Uri string using the separate parts of an URI. + * of an URI. + * + * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @param uEntity The Software Entity in the role of a service or in the role of an application. + * @param uResource The resource is something that is manipulated by a service such as a Door. + * + * @return Returns the uProtocol URI string from an URI data object + * that can be used as a sink or a source in a uProtocol publish communication. + */ + static String toShortUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { + return toShortUri(new UUri(uAuthority, uEntity, uResource)); + } + + + + + private static String buildResourcePartOfUri(UResource uResource, boolean shortUri) { + if (uResource.isEmpty()) { + return ""; + } + StringBuilder sb = new StringBuilder("/"); + if (shortUri) { + uResource.id().ifPresent(sb::append); + } else { + sb.append(uResource.name()); + uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); + uResource.message().ifPresent(message -> sb.append("#").append(message)); + } + + return sb.toString(); + } + + /** + * Create the service part of the uProtocol URI from an software entity object. + * @param use Software Entity representing a service or an application. + */ + private static String buildSoftwareEntityPartOfUri(UEntity use, boolean shortUri) { + StringBuilder sb = new StringBuilder(shortUri? use.id().get().toString() : use.name().trim()); + sb.append("/"); + use.version().ifPresent(sb::append); + + return sb.toString(); + } + + + /** + * Create the authority part of the uProtocol URI from an authority object. + * @param Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @return Returns the String representation of the Authority in the uProtocol URI. + */ + private static String buildAuthorityPartOfUri(UAuthority Authority, boolean shortUri) { + if (Authority.isLocal()) { + return "/"; + } + StringBuilder partialURI = new StringBuilder("//"); + if (shortUri) { + final Optional maybeAddress = Authority.address(); + if (maybeAddress.isPresent()) { + partialURI.append(maybeAddress.get().getHostAddress()); + } + return partialURI.toString(); + } + final Optional maybeDevice = Authority.device(); + final Optional maybeDomain = Authority.domain(); + + if (maybeDevice.isPresent()) { + partialURI.append(maybeDevice.get()); + maybeDomain.ifPresent(domain -> partialURI.append(".")); + } + maybeDomain.ifPresent(partialURI::append); + + return partialURI.toString(); + } + + /** + * Deserialize a String into a UUri object. + * @param uProtocolUri A long format uProtocol URI. + * @return Returns an UUri data object. + */ + @Override + public UUri deserialize(String uProtocolUri) { + if (uProtocolUri == null || uProtocolUri.isBlank()) { + return UUri.empty(); + } + + String uri = uProtocolUri.contains(":") ? uProtocolUri.substring(uProtocolUri.indexOf(":")+1) : uProtocolUri + .replace('\\', '/'); + + boolean isLocal = !uri.startsWith("//"); + + final String[] uriParts = uri.split("/"); + final int numberOfPartsInUri = uriParts.length; + + if(numberOfPartsInUri == 0 || numberOfPartsInUri == 1) { + return isLocal ? UUri.empty() : + new UUri(UAuthority.remote("", ""), UEntity.empty(), UResource.empty()); + } + + String useName; + String useVersion = ""; + + UResource uResource; + + UAuthority uAuthority; + if(isLocal) { + uAuthority = UAuthority.local(); + useName = uriParts[1]; + if (numberOfPartsInUri > 2) { + useVersion = uriParts[2]; + + uResource = numberOfPartsInUri > 3 ? UResource.fromString(uriParts[3]) : UResource.empty(); + + } else { + uResource = UResource.empty(); + } + } else { + String[] authorityParts = uriParts[2].split("\\."); + String device = authorityParts[0]; + String domain = ""; + if (authorityParts.length > 1) { + domain = Arrays.stream(authorityParts) + .skip(1) + .collect(Collectors.joining(".")); + } + uAuthority = UAuthority.remote(device, domain); + + if (uriParts.length > 3) { + useName = uriParts[3]; + if (numberOfPartsInUri > 4) { + useVersion = uriParts[4]; + + uResource = numberOfPartsInUri > 5 ? UResource.fromString(uriParts[5]) : UResource.empty(); + + } else { + uResource = UResource.empty(); + } + } else { + return new UUri(uAuthority, UEntity.empty(), UResource.empty()); + } + + } + + // Try and fetch the uE ID in the name portion of the string + Short maybeUeId = null; + if (!useName.isEmpty()) { + try { + maybeUeId = Short.parseShort(useName); + } catch (NumberFormatException e) { + maybeUeId = null; + + } + } + return new UUri(uAuthority, new UEntity(useName, useVersion.isBlank()? null : useVersion, maybeUeId), uResource); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java new file mode 100644 index 00000000..71727326 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.serializer; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.datamodel.UAuthority.AddressType; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.Arrays; +import java.util.Optional; + +/** + * UUri Factory used to build different types of UUri (long, short, micro), and UUri objects themselves + * for the various use cases found in uProtocol specifications. + * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + */ +public class MicroUriSerializer implements UriSerializer { + + static final int LOCAL_MICRO_URI_LENGTH = 8; // local micro URI length + + static final int IPV4_MICRO_URI_LENGTH = 12; // IPv4 micro URI length + + static final int IPV6_MICRO_URI_LENGTH = 24; // IPv6 micro Uri length + + + /** + * Serialize a UUri into a byte[] following the Micro-URI specifications + * + * @param Uri The URI data object. + * @return Returns the serialized URI into a byte[] + */ + @Override + public byte[] serialize(UUri Uri) { + if (Uri == null || Uri.isEmpty()) { + return new byte[0]; + } + + Optional maybeAddress = Uri.uAuthority().address(); + Optional maybeUeId = Uri.uEntity().id(); + Optional maybeUResourceId = Uri.uResource().id(); + if (!maybeUeId.isPresent() || !maybeUResourceId.isPresent()) { + return new byte[0]; + } + + // Remote Uri but the address is missing + if (!maybeAddress.isPresent() && Uri.uAuthority().isRemote()) { + return new byte[0]; + } + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + // UP_VERSION + os.write(0x1); + + // TYPE + if (Uri.uAuthority().isLocal()) { + os.write(0x0); + } else { + os.write(maybeAddress.get() instanceof Inet4Address ? 1 : 2); + } + + // URESOURCE_ID + os.write(maybeUResourceId.get()>>8); + os.write(maybeUResourceId.get()); + + // UAUTHORITY_ADDRESS + if (!Uri.uAuthority().isLocal()) { + try { + os.write(maybeAddress.get().getAddress()); + } catch (IOException e) { + return new byte[0]; + } + } + + // UENTITY_ID + os.write(maybeUeId.get()>>8); + os.write(maybeUeId.get()); + + // UENTITY_VERSION + String version = Uri.uEntity().version().orElse(""); + if (version.isEmpty()) { + os.write((byte)0); + os.write((byte)0); + } else { + String[] parts = version.split("\\."); + if (parts.length > 1) { + int major = (Integer.parseInt(parts[0]) << 3) + (Integer.parseInt(parts[1]) >> 8); + os.write((byte)major); + os.write((byte)Integer.parseInt(parts[1])); + } else { + os.write(Integer.parseInt(parts[0])<<3); + os.write(0); + } + } + return os.toByteArray(); + + } + + + /** + * Deserialize a byte[] into a UUri object + * @param microUri A byte[] uProtocol micro URI. + * @return Returns an URI data object. + */ + @Override + public UUri deserialize(byte[] microUri) { + if (microUri == null || microUri.length < LOCAL_MICRO_URI_LENGTH ) { + return UUri.empty(); + } + + // Need to be version 1 + if (microUri[0] != 0x1) { + return UUri.empty(); + } + + int uResourceId = ((microUri[2] & 0xFF) << 8) | (microUri[3] & 0xFF); + + Optional maybeAddress = Optional.empty(); + + Optional type = AddressType.from(microUri[1]); + + // Validate Type is found + if (!type.isPresent()) { + return UUri.empty(); + } + + // Validate that the microUri is the correct length for the type + if (type.get() == AddressType.LOCAL && microUri.length != LOCAL_MICRO_URI_LENGTH) { + return UUri.empty(); + } + else if (type.get() == AddressType.IPv4 && microUri.length != IPV4_MICRO_URI_LENGTH) { + return UUri.empty(); + } + else if (type.get() == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LENGTH) { + return UUri.empty(); + } + + int index = 4; + if (!(type.get() == AddressType.LOCAL)) { + try { + maybeAddress = Optional.of(InetAddress.getByAddress( + Arrays.copyOfRange(microUri, index, (type.get() == AddressType.IPv4) ? 8 : 20))); + } catch (Exception e) { + maybeAddress = Optional.empty(); + } + index += type.get() == AddressType.IPv4 ? 4 : 16; + } + + int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); + + int ueVersion = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); + String ueVersionString = String.valueOf(ueVersion >> 11); + + if (ueVersion == 0) { + ueVersionString = null; // no version provided + } + else if ((ueVersion & 0x7FF) != 0) { + ueVersionString += "." + (ueVersion & 0x7FF); + } + + return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), + UEntity.fromId(ueVersionString, (short)ueId), + UResource.fromId((short)uResourceId)); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java new file mode 100644 index 00000000..5fd83f3c --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.serializer; + +import org.eclipse.uprotocol.uri.datamodel.UUri; + +/** + * UUri serializer that will serialize to either Long form as a string or short form as a byte[]. + * + * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + * + * @param T The serialization formation + */ +public interface UriSerializer { + + /** + * Deserialize from the format to a UUri + * @param uri serialized UUri + * @return deserialized UUri object + */ + public UUri deserialize(T uri); + + /** + * Serialize from a UUri to the format + * @param uri UUri object to be serialized to the format T + * @return serialized UUri + */ + public T serialize(UUri uri); + + /** + * Long form serializer + */ + public static LongUriSerializer LONG = new LongUriSerializer(); + + /** + * Micro form serializer + */ + public static MicroUriSerializer MICRO = new MicroUriSerializer(); + +} diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java new file mode 100644 index 00000000..50b0f44f --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java @@ -0,0 +1,24 @@ +package org.eclipse.uprotocol.uri.serializer; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +public class UriSerializerTest { + + @Test + @DisplayName("Test using the serializers") + public void test_using_the_serializers() { + final UUri uri = new UUri(UAuthority.local(), UEntity.fromName("hartley"), UResource.forRpc("raise")); + final String strUri = UriSerializer.LONG.serialize(uri); + assertEquals("/hartley//rpc.raise", strUri); + final UUri uri2 = UriSerializer.LONG.deserialize(strUri); + assertTrue(uri.equals(uri2)); + } + +} diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index b895e924..cc86dd81 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -155,7 +155,7 @@ public void test_validateRpcResponse_with_invalid_rpc_response_type() { @DisplayName("Test validateLongUUri with valid URI") public void test_validateLongUUri_with_valid_uri() { final UUri uri = UriFactory.parseFromUri("/hartley//rpc.echo"); - final UStatus status = UriValidator.validateLongUUri(uri.uProtocolUri()); + final UStatus status = UriValidator.validateLongUUri(UriFactory.buildUProtocolUri(uri)); assertEquals(UStatus.ok(), status); } @@ -174,7 +174,7 @@ public void test_validateEqualsShortMicroUri_with_invalid_uri() { final String shortUri = "/0/1/1"; final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x10,0x0}; final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); - assertEquals("Short URI Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='unknown', version='1', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} and Micro Uri Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='unknown', version='2', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} are not equal.", status.msg()); + assertEquals("Short URI Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='0', version='1', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} and Micro Uri Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='0', version='2', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} are not equal.", status.msg()); } @Test From e97fe7b71f1ed34e962258217150effd04b62183 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 12 Sep 2023 11:01:56 -0400 Subject: [PATCH 27/52] Additional clean up and improvements for UUri --- .../uprotocol/uri/datamodel/UAuthority.java | 15 + .../uprotocol/uri/datamodel/UEntity.java | 11 + .../uprotocol/uri/datamodel/UResource.java | 15 +- .../eclipse/uprotocol/uri/datamodel/UUri.java | 44 +-- .../uprotocol/uri/factory/UriFactory.java | 37 +-- ...erializer.java => BytesUriSerializer.java} | 37 +-- ...rializer.java => StringUriSerializer.java} | 6 +- .../uri/serializer/UriSerializer.java | 6 +- .../uprotocol/uri/validator/UriValidator.java | 1 + .../uprotocol/uri/datamodel/UUriTest.java | 14 - .../uprotocol/uri/factory/UriFactoryTest.java | 312 ------------------ .../uri/serializer/UriSerializerTest.java | 2 + .../uri/validator/UriValidatorTest.java | 6 +- 13 files changed, 97 insertions(+), 409 deletions(-) rename src/main/java/org/eclipse/uprotocol/uri/serializer/{MicroUriSerializer.java => BytesUriSerializer.java} (84%) rename src/main/java/org/eclipse/uprotocol/uri/serializer/{LongUriSerializer.java => StringUriSerializer.java} (97%) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 68cde826..17d68a81 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -191,6 +191,21 @@ public boolean isMarkedRemote() { return markedRemote; } + /** + * Returns true if UAuthority contains both address and names meaning the UAuthority is resolved. + * @return Returns true if UAuthority contains both address and names meaning the UAuthority is resolved. + */ + public boolean isResolved() { + boolean isResolved = false; + try { + isResolved = address().isPresent() && device().isPresent() && + InetAddress.getByName(device().get()).equals(address().get()); + } catch (Exception e) { + isResolved = false; + } + return isResolved; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 9a84415d..014a5b67 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -79,6 +79,7 @@ public static UEntity fromName(String name) { * @return Returns a UEntity with id but unknown name. */ public static UEntity fromId(String version, Short id) { + Objects.requireNonNull(id, "ID must be supplied"); return new UEntity(String.valueOf(id), version, id); } @@ -142,4 +143,14 @@ public String toString() { + ", version='" + (version == null ? "latest" : version) + '\'' + ", id='" + (id == null ? "null" : id) + '\'' + '}'; } + + + /** + * Return true if the UEntity contains both the name and IDs meaning it is resolved + * UEntity. Resolved UEntity contains name and id when the name and ID are not the same + * @return Returns true of this resource contains resolved information + */ + public boolean isResolved() { + return (id != null) && (name != null) && (id != Short.valueOf(name)); + } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index bfa1f0de..1441bdc7 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -75,6 +75,7 @@ public UResource(String name, String instance, String message, Short id) { } else { this.id = id; } + } @@ -86,7 +87,7 @@ public UResource(String name, String instance, String message, Short id) { public static UResource fromId(Short id) { Objects.requireNonNull(id, "id Required"); if (id == 0) { - return new UResource(new String("rpc"), new String("response"), null, id); + return RESPONSE; } return new UResource(UNKNOWN_NAME, null, null, id); } @@ -139,7 +140,7 @@ public static UResource forRpc(String commandName, Short id) { * @param resourceString String that contains the UResource information. * @return Returns a UResource object */ - public static UResource fromString(String resourceString) { + public static UResource parseFromString(String resourceString) { Objects.requireNonNull(resourceString, " Resource must have a command name."); String[] parts = resourceString.split("#"); String nameAndInstance = parts[0]; @@ -263,4 +264,14 @@ public String toString() { ", id='" + (id == null ? "null" : id) + '\'' + '}'; } + + /** + * Return true if this resource contains both ID and names. + * Method type of UResource requires name, instance, and ID where a topic + * type of UResource also requires message to not be null + * @return Returns true of this resource contains resolved information + */ + public boolean isResolved() { + return (id != null) && (name != null) && (instance != null) && (isRPCMethod() || (message == null)); + } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 56f88332..2c8707a2 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -21,8 +21,8 @@ package org.eclipse.uprotocol.uri.datamodel; +import java.net.InetAddress; import java.util.Objects; -import java.util.Optional; /** * Data representation of an URI. @@ -39,16 +39,14 @@ public class UUri { private static final UUri EMPTY = new UUri(UAuthority.empty(), UEntity.empty(), UResource.empty()); - protected final UAuthority uAuthority; - protected final UEntity uEntity; - protected final UResource uResource; + private final UAuthority uAuthority; + private final UEntity uEntity; + private final UResource uResource; - // Transport specific ID - private transient Integer id; /** * Create a full URI. - * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @param uAuthority The Authority represents the deployment location of a specific Software Entity . * @param uEntity The USE in the role of a service or in the role of an application. * @param uResource The resource is something that is manipulated by a service such as a Door. */ @@ -61,7 +59,7 @@ public UUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { /** * Create an URI for a resource. This will match all the specific instances of the resource, * for example all the instances of the vehicle doors. - * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @param uAuthority The Authority represents the deployment location of a specific Software Entity. * @param uEntity The USE in the role of a service or in the role of an application. * @param uResource The resource is something that is manipulated by a service such as a Door. */ @@ -69,6 +67,24 @@ public UUri(UAuthority uAuthority, UEntity uEntity, String uResource) { this(uAuthority, uEntity, UResource.fromName(uResource)); } + /** + * Create a UUri containing only IDs + * @param uAuthority The internet address of the device or nyll if it is local + * @param ueId The id of the ue + * @param version The version of the ue + * @param uResource The id of the resource + * @return Returns a UUri containing only IDs + */ + public static UUri micrUUri(InetAddress address, Short ueId, Integer version, Short uResource) { + Objects.requireNonNull(ueId, "Micro Uri must have an ueId"); + Objects.requireNonNull(version, "Micro Uri must have a version"); + Objects.requireNonNull(uResource, "Micro Uri must have an uResource"); + return new UUri(address == null ? UAuthority.local() : UAuthority.remote(address), + UEntity.fromId(String.valueOf(version), ueId), UResource.fromId(uResource)); + } + + + /** * Static factory method for creating an empty uri, to avoid working with null
* @return Returns an empty ultify uri to avoid working with null. @@ -130,16 +146,4 @@ public String toString() { '}'; } - /** - * Method to get/set the ID used to represent the UUri as an ID in the transport layer. - * @param id The ID used to represent the UUri as an ID in the transport layer. - * @return Returns the ID used to represent the UUri as an ID in the transport layer. - */ - public Optional id(Integer id) { - if (id != null) { - this.id = id; - } - return Optional.ofNullable(this.id); - } - } \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java index c3fd5b73..da819a1b 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java @@ -191,23 +191,14 @@ static byte[] buildUProtocolMicroUri(UUri Uri) { // UENTITY_ID os.write(maybeUeId.get()>>8); os.write(maybeUeId.get()); - - // UENTITY_VERSION + + // UE_VERSION String version = Uri.uEntity().version().orElse(""); - if (version.isEmpty()) { - os.write((byte)0); - os.write((byte)0); - } else { - String[] parts = version.split("\\."); - if (parts.length > 1) { - int major = (Integer.parseInt(parts[0]) << 3) + (Integer.parseInt(parts[1]) >> 8); - os.write((byte)major); - os.write((byte)Integer.parseInt(parts[1])); - } else { - os.write(Integer.parseInt(parts[0])<<3); - os.write(0); - } - } + os.write(version.isEmpty() ? (byte)0 : Integer.parseInt(version.split("\\.")[0])); + + // UNUSED + os.write((byte)0); + return os.toByteArray(); } @@ -471,20 +462,14 @@ else if (type.get() == AddressType.IPv6 && microUri.length != UriFactory.IPV6_MI index += type.get() == AddressType.IPv4 ? 4 : 16; } + // UENTITY_ID int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - int ueVersion = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - String ueVersionString = String.valueOf(ueVersion >> 11); + // UE_VERSION + int uiVersion = microUri[index++]; - if (ueVersion == 0) { - ueVersionString = null; // no version provided - } - else if ((ueVersion & 0x7FF) != 0) { - ueVersionString += "." + (ueVersion & 0x7FF); - } - return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), - UEntity.fromId(ueVersionString, (short)ueId), + UEntity.fromId(String.valueOf(uiVersion), (short)ueId), UResource.fromId((short)uResourceId)); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java similarity index 84% rename from src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java rename to src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java index 71727326..50c812c1 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java @@ -39,7 +39,7 @@ * for the various use cases found in uProtocol specifications. * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ -public class MicroUriSerializer implements UriSerializer { +public class BytesUriSerializer implements UriSerializer { static final int LOCAL_MICRO_URI_LENGTH = 8; // local micro URI length @@ -100,22 +100,13 @@ public byte[] serialize(UUri Uri) { os.write(maybeUeId.get()>>8); os.write(maybeUeId.get()); - // UENTITY_VERSION + // UE_VERSION String version = Uri.uEntity().version().orElse(""); - if (version.isEmpty()) { - os.write((byte)0); - os.write((byte)0); - } else { - String[] parts = version.split("\\."); - if (parts.length > 1) { - int major = (Integer.parseInt(parts[0]) << 3) + (Integer.parseInt(parts[1]) >> 8); - os.write((byte)major); - os.write((byte)Integer.parseInt(parts[1])); - } else { - os.write(Integer.parseInt(parts[0])<<3); - os.write(0); - } - } + os.write(version.isEmpty() ? (byte)0 : Integer.parseInt(version.split("\\.")[0])); + + // UNUSED + os.write((byte)0); + return os.toByteArray(); } @@ -170,20 +161,14 @@ else if (type.get() == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LEN index += type.get() == AddressType.IPv4 ? 4 : 16; } + // UENTITY_ID int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - int ueVersion = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - String ueVersionString = String.valueOf(ueVersion >> 11); + // UE_VERSION + int uiVersion = microUri[index++]; - if (ueVersion == 0) { - ueVersionString = null; // no version provided - } - else if ((ueVersion & 0x7FF) != 0) { - ueVersionString += "." + (ueVersion & 0x7FF); - } - return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), - UEntity.fromId(ueVersionString, (short)ueId), + UEntity.fromId(String.valueOf(uiVersion), (short)ueId), UResource.fromId((short)uResourceId)); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java similarity index 97% rename from src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java rename to src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java index 3baf7bea..1d6ee16f 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java @@ -34,7 +34,7 @@ * UUri Serializer that serializes a UUri to a string (long or long form) per * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ -public class LongUriSerializer implements UriSerializer { +public class StringUriSerializer implements UriSerializer { /** * Serialize the UUri object into a String containing either long or short form. @@ -212,7 +212,7 @@ public UUri deserialize(String uProtocolUri) { if (numberOfPartsInUri > 2) { useVersion = uriParts[2]; - uResource = numberOfPartsInUri > 3 ? UResource.fromString(uriParts[3]) : UResource.empty(); + uResource = numberOfPartsInUri > 3 ? UResource.parseFromString(uriParts[3]) : UResource.empty(); } else { uResource = UResource.empty(); @@ -233,7 +233,7 @@ public UUri deserialize(String uProtocolUri) { if (numberOfPartsInUri > 4) { useVersion = uriParts[4]; - uResource = numberOfPartsInUri > 5 ? UResource.fromString(uriParts[5]) : UResource.empty(); + uResource = numberOfPartsInUri > 5 ? UResource.parseFromString(uriParts[5]) : UResource.empty(); } else { uResource = UResource.empty(); diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index 5fd83f3c..e23c24cb 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -24,7 +24,7 @@ import org.eclipse.uprotocol.uri.datamodel.UUri; /** - * UUri serializer that will serialize to either Long form as a string or short form as a byte[]. + * UUri serializer that will serialize to either String or byte[] the UUri object. * * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc * @@ -49,11 +49,11 @@ public interface UriSerializer { /** * Long form serializer */ - public static LongUriSerializer LONG = new LongUriSerializer(); + public static StringUriSerializer LONG = new StringUriSerializer(); /** * Micro form serializer */ - public static MicroUriSerializer MICRO = new MicroUriSerializer(); + public static BytesUriSerializer MICRO = new BytesUriSerializer(); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 4b4ea7b4..62f56554 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -100,4 +100,5 @@ public static UStatus validateEqualsShortMicroUri(String shortUri, byte[] microU } return UStatus.ok(); } + } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index e146253a..3b159f96 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -163,18 +163,4 @@ public void test_is_empty() { assertTrue(uri2.isEmpty()); } - @Test - @DisplayName("Test getting and setting id") - public void test_getting_and_setting_id() { - UAuthority uAuthorityRemote = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); - UUri uri = new UUri(uAuthorityRemote, use, uResource); - - assertTrue(uri.id(null).isEmpty()); - uri.id(1); - assertTrue(uri.id(null).isPresent()); - assertEquals(1, uri.id(null).get()); - } - } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java index e4d3b20c..b3d0e598 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java @@ -1049,317 +1049,5 @@ public void test_build_short_uri_from_remote_uri_missing_address() { String ucustomUri = UriFactory.buildUProtocolShortUri(uAuthority, use, uResource); assertEquals("///", ucustomUri); } - - @Test - @DisplayName("Test Create a uProtocol Micro URI with empty URI") - public void test_build_micro_uri_from_uri_missing_ids() { - UUri Uri = UUri.empty(); - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(Uri); - assertEquals(0, uProtocolUri.length); - } - - - @Test - @DisplayName("Test Create a uProtocol Micro URI with remote URI without uEntity") - public void test_build_micro_uri_from_remote_uri_missing_uentity() { - String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; - InetAddress address = null; - try { - address = InetAddress.getByName(ipv6Address); - } - catch (UnknownHostException e) { - e.printStackTrace(); - } - UAuthority uAuthority = UAuthority.remote(address); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, UEntity.empty(), UResource.empty())); - assertEquals(0, uProtocolUri.length); - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI for local UAuthority") - public void test_build_micro_uri_from_local_uri_simple_version() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", "1", (short)5); - UResource uResource = new UResource("door", "front_left", "Door", (short)3); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); - assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local - assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) - assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) - assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) - assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) - assertEquals(1<<3, uProtocolUri[6]); // UEntity Version (MSB) - assertEquals(0, uProtocolUri[7]); // UEntity Version (LSB) - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI for local UAuthority") - public void test_build_micro_uri_from_local_uri() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", "1.1", (short)5); - UResource uResource = new UResource("door", "front_left", "Door", (short)3); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); - assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local - assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) - assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) - assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) - assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) - assertEquals(1<<3, uProtocolUri[6]); // UEntity Version (MSB) - assertEquals(1, uProtocolUri[7]); // UEntity Version (LSB) - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI for local UAuthority large minor version") - public void test_build_micro_uri_from_local_uri_large_minor_version() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", "1.599", (short)5); - UResource uResource = new UResource("door", "front_left", "Door", (short)3); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); - assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local - assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) - assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) - assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) - assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) - assertEquals(10, uProtocolUri[6]); // UEntity Version (MSB) - assertEquals(599 & 0xff, uProtocolUri[7]); // UEntity Version (LSB) - } - - - @Test - @DisplayName("Test Create a uProtocol Micro URI for local UAuthority no version") - public void test_build_micro_uri_from_local_uri_no_version() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", null, (short)5); - UResource uResource = new UResource("door", "front_left", "Door", (short)3); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(UriFactory.LOCAL_MICRO_URI_LENGTH, uProtocolUri.length); - assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(AddressType.LOCAL.getValue(), uProtocolUri[1]); // local - assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) - assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) - assertEquals(0, uProtocolUri[4]); // UEntity ID (MSB) - assertEquals(5, uProtocolUri[5]); // UEntity ID (LSB) - assertEquals((byte)0, uProtocolUri[6]); // UEntity Version (MSB) - assertEquals((byte)0, uProtocolUri[7]); // UEntity Version (LSB) - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI to byte[] then call parseFromMicroUri to convert back to UUri") - public void test_build_micro_uri_from_local_uri_then_parse_back_to_uri() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.fromId("1.599", (short)5); - UResource uResource = UResource.fromId((short)3); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); - assertEquals(uAuthority, Uri.uAuthority()); - assertEquals(use, Uri.uEntity()); - assertEquals(uResource, Uri.uResource()); - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI for remote IPv4 UAuthority") - public void test_build_micro_uri_from_remote_ipv4_address() throws UnknownHostException { - final InetAddress address = InetAddress.getByName("127.0.0.1"); - final UAuthority uAuthority = UAuthority.remote(address); - final UEntity use = UEntity.fromId(null, (short)5); - final UResource uResource = UResource.fromId((short)3); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - assertEquals(UriFactory.IPV4_MICRO_URI_LENGTH, uProtocolUri.length); - assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(AddressType.IPv4.getValue(), uProtocolUri[1]); // IPv4 - assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) - assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) - InetAddress address2 = InetAddress.getByAddress(Arrays.copyOfRange(uProtocolUri, 4, 8)); - assertEquals(address, address2); - assertEquals(0, uProtocolUri[8]); // UEntity ID (MSB) - assertEquals(5, uProtocolUri[9]); // UEntity ID (LSB) - assertEquals((byte)0, uProtocolUri[10]); // UEntity Version (MSB) - assertEquals((byte)0, uProtocolUri[11]); // UEntity Version (LSB) - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI for remote IPv6 UAuthority") - public void test_build_micro_uri_from_remote_ipv6_address() throws UnknownHostException { - final InetAddress address = InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"); - final UAuthority uAuthority = UAuthority.remote(address); - final UEntity use = UEntity.fromId(null, (short)5); - final UResource uResource = UResource.fromId((short)3); - final UUri uri = new UUri(uAuthority, use, uResource); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(uri); - assertEquals(UriFactory.IPV6_MICRO_URI_LENGTH, uProtocolUri.length); - assertEquals(1, uProtocolUri[0]); // version 1 - assertEquals(AddressType.IPv6.getValue(), uProtocolUri[1]); // IPv4 - assertEquals(0, uProtocolUri[2]); // UResource ID (MSB) - assertEquals(3, uProtocolUri[3]); // UResource ID (LSB) - InetAddress address2 = InetAddress.getByAddress(Arrays.copyOfRange(uProtocolUri, 4, 20)); - assertEquals(address, address2); - assertEquals(0, uProtocolUri[20]); // UEntity ID (MSB) - assertEquals(5, uProtocolUri[21]); // UEntity ID (LSB) - assertEquals((byte)0, uProtocolUri[22]); // UEntity Version (MSB) - assertEquals((byte)0, uProtocolUri[23]); // UEntity Version (LSB) - final UUri uri2 = UriFactory.parseFromMicroUri(uProtocolUri); - assertEquals(uri.toString(), uri2.toString()); - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI with null URI") - public void test_build_micro_uri_from_null_uri() { - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(null); - assertEquals(0, uProtocolUri.length); - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI with empty URI") - public void test_build_micro_uri_from_empty_uri() { - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(UUri.empty()); - assertEquals(0, uProtocolUri.length); - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI without UResource id") - public void test_build_micro_uri_from_uri_missing_uresource_id() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", "1", (short)5); - UResource uResource = UResource.empty(); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - - assertEquals(0, uProtocolUri.length); - } - - @Test - @DisplayName("Test Create a uProtocol Micro URI with invalid address") - public void test_build_micro_uri_from_uri_invalid_address() throws UnknownHostException { - InetAddress address = InetAddress.getByName("example.com"); - UAuthority uAuthority = UAuthority.remote(address); - UEntity use = new UEntity("body.access", "1", (short)5); - UResource uResource = UResource.fromName("door"); - - byte[] uProtocolUri = UriFactory.buildUProtocolMicroUri(new UUri(uAuthority, use, uResource)); - - assertEquals(0, uProtocolUri.length); - } - - @Test - @DisplayName("Test parse micro URI from empty byte[]") - public void test_parse_micro_uri_from_empty_byte_array() { - byte[] uProtocolUri = new byte[0]; - UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); - assertEquals(UUri.empty(), Uri); - } - - @Test - @DisplayName("Test create and print long, short, and micro URIs using core.usubscription for spec examples") - public void test_create_and_print_long_short_and_micro_uris_using_core_usubscription_for_spec_examples() { - final UEntity ue = new UEntity("core.usubscription", "2", (short)0); - final UResource resource = UResource.forRpc("Subscribe", (short)1); - - UUri Uri = new UUri(UAuthority.local(), ue, resource); - String longUri = UriFactory.buildUProtocolUri(Uri); - String shortUri = UriFactory.buildUProtocolShortUri(Uri); - byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); - assertEquals("/core.usubscription/2/rpc.Subscribe", longUri); - assertEquals("/0/2/1", shortUri); - - System.out.println(Arrays.toString(microUri)); - assertEquals("[1, 0, 0, 1, 0, 0, 16, 0]", Arrays.toString(microUri)); - } - - @Test - @DisplayName("Test create and print remote ipv6_long, short, and micro URIs using core.usubscription for spec examples") - public void test_create_and_print_remote_ipv6_long_short_and_micro_uris_using_core_usubscription_for_spec_examples() throws UnknownHostException { - final UEntity ue = new UEntity("core.usubscription", "2", (short)0); - final UResource resource = UResource.forRpc("Subscribe", (short)1); - final UAuthority authority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UUri Uri = new UUri(authority, ue, resource); - String longUri = UriFactory.buildUProtocolUri(Uri); - String shortUri = UriFactory.buildUProtocolShortUri(Uri); - byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); - assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/core.usubscription/2/rpc.Subscribe", longUri); - assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/0/2/1", shortUri); - - System.out.println(Arrays.toString(microUri)); - assertEquals("[1, 2, 0, 1, 32, 1, 13, -72, -123, -93, 0, 0, 0, 0, -118, 46, 3, 112, 115, 52, 0, 0, 16, 0]", Arrays.toString(microUri)); - } - - - @Test - @DisplayName("Test parsing a uProtocol Micro URI with invalid version") - public void test_parsing_micro_uri_bad_version_byte() throws UnknownHostException { - byte[] uProtocolUri = new byte[] {0,0,0,0,0,0,0,0}; - final UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); - assertEquals(UUri.empty(), Uri); - } - - @Test - @DisplayName("Test parsing a uProtocol Micro URI with invalid type") - public void test_parsing_micro_uri_bad_type_byte() throws UnknownHostException { - byte[] uProtocolUri = new byte[] {0x1,0xf,0,0,0,0,0,0}; - final UUri Uri = UriFactory.parseFromMicroUri(uProtocolUri); - assertEquals(UUri.empty(), Uri); - } - - @Test - @DisplayName("Test create and convert to and from IPv4 micro URI") - public void test_create_and_convert_to_from_ipv4_micro_uri() throws UnknownHostException { - final UEntity ue = UEntity.fromId("2", (short)0); - final UResource resource = UResource.fromId((short)1); - final UAuthority authority = UAuthority.remote(InetAddress.getByName("192.168.1.100")); - UUri Uri = new UUri(authority, ue, resource); - byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); - UUri uri2 = UriFactory.parseFromMicroUri(microUri); - assertEquals(Uri, uri2); - } - - @Test - @DisplayName("Test parse micro URI using invalid type length") - public void test_parse_micro_uri_using_invalid_type_lengths_address() throws UnknownHostException { - byte[] uProtocolUri = new byte[] {0x1,0x0,0,0,0,0,0,0,0}; - // test local (too large) - UUri uriLocalTest = UriFactory.parseFromMicroUri(uProtocolUri); - assertTrue(uriLocalTest.isEmpty()); - - // test IPv4 (too small) - uProtocolUri[1] = 0x1; - UUri uriIPv4Test = UriFactory.parseFromMicroUri(uProtocolUri); - assertTrue(uriIPv4Test.isEmpty()); - - // Test IPv6 too small - uProtocolUri[1] = 0x2; - UUri uriIPv6Test = UriFactory.parseFromMicroUri(uProtocolUri); - assertTrue(uriIPv6Test.isEmpty()); - } - - @Test - @DisplayName("Test build micro URI with remote authority with no address") - public void test_build_micro_uri_with_remote_authority_with_no_address() throws UnknownHostException { - final UEntity ue = UEntity.fromId("2", (short)0); - final UResource resource = UResource.fromId((short)1); - final UAuthority authority = UAuthority.remote("VCU", null); - UUri Uri = new UUri(authority, ue, resource); - byte[] microUri = UriFactory.buildUProtocolMicroUri(Uri); - assertEquals(microUri.length, 0); - } - - @Test - @DisplayName("Test parse micro uri with invalid IPv4 address") - public void test_parse_micro_uri_with_invalid_ipv4_address() throws UnknownHostException { - byte[] uProtocolUri = new byte[] {0x1,0x1,-128,-128,-128,-128,0,0}; - UUri uriLocalTest = UriFactory.parseFromMicroUri(uProtocolUri); - assertTrue(uriLocalTest.isEmpty()); - } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java index 50b0f44f..e46adba3 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java @@ -19,6 +19,8 @@ public void test_using_the_serializers() { assertEquals("/hartley//rpc.raise", strUri); final UUri uri2 = UriSerializer.LONG.deserialize(strUri); assertTrue(uri.equals(uri2)); + + } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index cc86dd81..991fba69 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -163,7 +163,7 @@ public void test_validateLongUUri_with_valid_uri() { @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI are identical") public void test_validateEqualsShortMicroUri_with_valid_uri() { final String shortUri = "/0/2/1"; - final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,2<<3,0x0}; + final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,2,0x0}; final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); assertEquals(UStatus.ok(), status); } @@ -172,7 +172,7 @@ public void test_validateEqualsShortMicroUri_with_valid_uri() { @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI are not identical") public void test_validateEqualsShortMicroUri_with_invalid_uri() { final String shortUri = "/0/1/1"; - final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x10,0x0}; + final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x2,0x0}; final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); assertEquals("Short URI Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='0', version='1', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} and Micro Uri Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='0', version='2', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} are not equal.", status.msg()); } @@ -181,7 +181,7 @@ public void test_validateEqualsShortMicroUri_with_invalid_uri() { @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI empty values") public void test_validateEqualsShortMicroUri_with_missing_parameters() { final String shortUri = "/0/1/1"; - final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x10,0x0}; + final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x1,0x0}; final UStatus status = UriValidator.validateEqualsShortMicroUri(null, microUri); assertEquals("Short Uri is invalid.", status.msg()); final UStatus status2 = UriValidator.validateEqualsShortMicroUri(shortUri, null); From e623b8c05ffe979dd52d33492710842fdaaa6c78 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 12 Sep 2023 22:32:46 -0400 Subject: [PATCH 28/52] Added isResolved() and isLocalFormat() Added these new APIs to UUri, UAuthority, UEntity, and UResource --- .../uprotocol/uri/datamodel/UAuthority.java | 34 +++++----- .../uprotocol/uri/datamodel/UEntity.java | 17 ++++- .../uprotocol/uri/datamodel/UResource.java | 6 +- .../eclipse/uprotocol/uri/datamodel/UUri.java | 28 ++++++-- .../uri/serializer/UriSerializer.java | 4 +- .../uri/datamodel/UAuthorityTest.java | 36 +++++++++- .../uprotocol/uri/datamodel/UEntityTest.java | 27 ++++++++ .../uri/datamodel/UResourceTest.java | 63 +++++++++++++++++ .../uprotocol/uri/datamodel/UUriTest.java | 68 +++++++++++++++++++ .../uri/serializer/UriSerializerTest.java | 4 +- 10 files changed, 254 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 17d68a81..03732d33 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -67,6 +67,7 @@ public class UAuthority { * @param domain The domain an software entity is deployed on, such as vehicle or backoffice. * @param address The device IP address. * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. + * @param addressName Indicates if the device name is an IP address */ private UAuthority(String device, String domain, InetAddress address, boolean markedRemote) { this.device = device == null ? null : device.toLowerCase(); @@ -121,7 +122,7 @@ public static UAuthority remote(String device, String domain, InetAddress addres // representation of an ip address if ( (device != null) && (addr == null) ) { try { - if ((device != null) && InetAddressValidator.getInstance().isValid(device)) { + if (InetAddressValidator.getInstance().isValid(device)) { addr = InetAddress.getByName(device); } else { addr = null; @@ -131,12 +132,6 @@ public static UAuthority remote(String device, String domain, InetAddress addres } } - // The IP address is populated but not the device name so set the device name - // to be the string representation of the IP address - if ((addr !=null) && (device == null)) { - device = addr.getHostAddress(); - } - return new UAuthority(device, domain, addr, true); } @@ -192,27 +187,32 @@ public boolean isMarkedRemote() { } /** - * Returns true if UAuthority contains both address and names meaning the UAuthority is resolved. + * Returns true if UAuthority is local or contains both address and names if the name was not populated with the + * string representation of the address * @return Returns true if UAuthority contains both address and names meaning the UAuthority is resolved. */ public boolean isResolved() { - boolean isResolved = false; - try { - isResolved = address().isPresent() && device().isPresent() && - InetAddress.getByName(device().get()).equals(address().get()); - } catch (Exception e) { - isResolved = false; - } - return isResolved; + return isLocal() || (address().isPresent() && device().isPresent()); + } + + /** + * Check if the UAuthority contains Long form URI (i.e. names). It will be long form + * if the UAuthority is resolved (meaning it has id and names) or there is no address since + * it has to has to have a device name. + * @return Returns true if the UAuthority contains Long form URI information (names) + */ + public boolean isLongForm() { + return isResolved() || !address().isPresent(); } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UAuthority that = (UAuthority) o; return markedRemote == that.markedRemote && Objects.equals(device, that.device) - && Objects.equals(domain, that.domain) && Objects.equals(address, that.address); + && Objects.equals(domain, that.domain) && Objects.equals(address, that.address) ; } @Override diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 014a5b67..9c1fb70a 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -151,6 +151,21 @@ public String toString() { * @return Returns true of this resource contains resolved information */ public boolean isResolved() { - return (id != null) && (name != null) && (id != Short.valueOf(name)); + boolean isResolved = !name.isBlank() && (id != null); + + try { + isResolved = (id != Short.valueOf(name)); + } catch (NumberFormatException e) { + return isResolved; + } + return isResolved; + } + + /** + * Check if the UEntity contains Long form URI information (uE name) + * @return Returns true if the UEntity contains Long form URI information (names) + */ + public boolean isLongForm() { + return isResolved() || !name.isBlank(); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 1441bdc7..41ac9f2c 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -272,6 +272,10 @@ public String toString() { * @return Returns true of this resource contains resolved information */ public boolean isResolved() { - return (id != null) && (name != null) && (instance != null) && (isRPCMethod() || (message == null)); + return (id != null) && isLongForm(); + } + + public boolean isLongForm() { + return !name.equals(UNKNOWN_NAME) && (instance != null) && (isRPCMethod() || (message != null)); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 2c8707a2..000c5be5 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -68,23 +68,21 @@ public UUri(UAuthority uAuthority, UEntity uEntity, String uResource) { } /** - * Create a UUri containing only IDs + * Create a Short UUri using only IDs containing only IDs * @param uAuthority The internet address of the device or nyll if it is local * @param ueId The id of the ue * @param version The version of the ue * @param uResource The id of the resource * @return Returns a UUri containing only IDs */ - public static UUri micrUUri(InetAddress address, Short ueId, Integer version, Short uResource) { - Objects.requireNonNull(ueId, "Micro Uri must have an ueId"); - Objects.requireNonNull(version, "Micro Uri must have a version"); - Objects.requireNonNull(uResource, "Micro Uri must have an uResource"); + public static UUri shortUUri(InetAddress address, Short ueId, Integer version, Short uResource) { + Objects.requireNonNull(ueId, "Short Uri must have an ueId"); + Objects.requireNonNull(version, "Short Uri must have a version"); + Objects.requireNonNull(uResource, "Short Uri must have an uResource"); return new UUri(address == null ? UAuthority.local() : UAuthority.remote(address), UEntity.fromId(String.valueOf(version), ueId), UResource.fromId(uResource)); } - - /** * Static factory method for creating an empty uri, to avoid working with null
* @return Returns an empty ultify uri to avoid working with null. @@ -146,4 +144,20 @@ public String toString() { '}'; } + /** + * Returns true if URI contains both names and numeric representations of the names inside + * its belly. + * @return Returns true if URI contains both names and numeric representations of the names inside + */ + public boolean isResolved() { + return uAuthority.isResolved() && uEntity.isResolved() && uResource.isResolved(); + } + + /** + * Check if the UEntity and UResource contains Long form URI information (names) + * @return Returns true if the UEntity and UResource contains Long form URI information (names) + */ + public boolean isLongForm() { + return isResolved() || uEntity.isLongForm() && uResource.isLongForm(); + } } \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index e23c24cb..3449479a 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -49,11 +49,11 @@ public interface UriSerializer { /** * Long form serializer */ - public static StringUriSerializer LONG = new StringUriSerializer(); + public static StringUriSerializer STRING = new StringUriSerializer(); /** * Micro form serializer */ - public static BytesUriSerializer MICRO = new BytesUriSerializer(); + public static BytesUriSerializer BYTES = new BytesUriSerializer(); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index 952e86a3..925b818f 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -30,7 +30,6 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.Objects; class UAuthorityTest { @@ -167,7 +166,7 @@ public void test_create_uAuthority_with_valid_ip_address() { InetAddress address = Inet6Address.getLoopbackAddress(); UAuthority remote = UAuthority.remote(address); - String expectedLocal = "UAuthority{device='127.0.0.1', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; + String expectedLocal = "UAuthority{device='null', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; InetAddress address2 = remote.address().get(); assertTrue(remote.address().isPresent()); assertEquals(address, address2); @@ -187,7 +186,7 @@ public void test_create_uAuthority_with_valid_ipv6_address() { } UAuthority remote = UAuthority.remote(address); - String expectedLocal = "UAuthority{device='2001:db8:85a3:0:0:8a2e:370:7334', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; + String expectedLocal = "UAuthority{device='null', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } @@ -198,4 +197,35 @@ public void test_create_uAuthority_with_valid_ipv4_address_in_device_name() { String expectedLocal = "UAuthority{device='192.168.1.100', domain='null', address='/192.168.1.100', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } + + + @Test + @DisplayName("Test isResolved() and isLongForm() with a resolved uAuthority") + public void test_isResolved_with_resolved_uAuthority() throws UnknownHostException { + UAuthority local = UAuthority.local(); + UAuthority remote = UAuthority.remote("192.168.1.100", null, InetAddress.getByName("192.168.1.100")); + UAuthority remote1 = UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")); + assertTrue(local.isResolved()); + assertTrue(local.isLongForm()); + assertTrue(remote.isResolved()); + assertTrue(remote.isLongForm()); + assertTrue(remote1.isResolved()); + assertTrue(remote1.isLongForm()); + } + + + @Test + @DisplayName("Test isResolved() and isLongForm() with a unresolved uAuthority") + public void test_isResolved_with_unresolved_uAuthority() throws UnknownHostException { + UAuthority remote = UAuthority.remote("vcu", "vin"); + UAuthority remote1 = UAuthority.remote(InetAddress.getByName("192.168.1.100")); + UAuthority remote2 = UAuthority.empty(); + assertFalse(remote.isResolved()); + assertTrue(remote.isLongForm()); + assertFalse(remote1.isResolved()); + assertFalse(remote1.isLongForm()); + assertTrue(remote2.isResolved()); + assertTrue(remote2.isLongForm()); + } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 3e07b665..301271b6 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -134,4 +134,31 @@ public void test_create_use_with_invalid_id() { assertEquals("UEntity{name='body.access', version='1', id='null'}", use.toString()); } + @Test + @DisplayName("Test isResolved and isLongForm() with valid resolved information") + public void test_isResolved_with_valid_resolved_data() { + UEntity use = new UEntity("body.access", "1", (short)0); + assertTrue(use.isResolved()); + assertTrue(use.isLongForm()); + UEntity use3 = new UEntity("2", null, (short)1); + assertTrue(use3.isResolved()); + assertTrue(use3.isLongForm()); + } + + @Test + @DisplayName("Test isResolved and isLongForm() with invalid resolved data") + public void test_isResolved_with_invalid_resolved_data() { + UEntity use = new UEntity("body.access", "1", null); + assertFalse(use.isResolved()); + assertTrue(use.isLongForm()); + UEntity use2 = UEntity.fromId(null, (short)1); + assertFalse(use2.isResolved()); + assertTrue(use2.isLongForm()); + + UEntity use3 = UEntity.empty(); + assertFalse(use3.isResolved()); + assertFalse(use3.isLongForm()); + } + + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index e5949135..622cdf32 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -260,4 +260,67 @@ public void test_create_request_UResource_passing_name_instance_and_id() { assertEquals((int)0, (int)uResource.id().get()); assertEquals("UResource{name='rpc', instance='null', message='null', id='0'}", uResource.toString()); } + + @Test + @DisplayName("Test isResolved with resolved UResources") + public void test_isResolved_with_resolved_UResources() { + UResource uResource = new UResource("door", "front_left", "Door", (short)5); + assertTrue(uResource.isResolved()); + UResource uResource2 = UResource.response(); + assertTrue(uResource2.isResolved()); + UResource uResource3 = UResource.forRpc("UpdateDoor", (short)5); + assertTrue(uResource3.isResolved()); + } + + @Test + @DisplayName("Test isResolved and isLongForm with unresolved UResources") + public void test_isResolved_with_unresolved_UResources() { + UResource uResource = new UResource("door", "front_left", "Door", null); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + UResource uResource2 = UResource.fromName("door"); + assertFalse(uResource2.isResolved()); + assertFalse(uResource2.isLongForm()); + UResource uResource3 = UResource.forRpc("UpdateDoor"); + assertFalse(uResource3.isResolved()); + assertTrue(uResource3.isLongForm()); + UResource uResource4 = UResource.fromId((short)4); + assertFalse(uResource4.isResolved()); + assertFalse(uResource4.isLongForm()); + + UResource uResource5 = UResource.fromNameWithInstance("door", "front_left"); + assertFalse(uResource5.isResolved()); + assertFalse(uResource5.isLongForm()); + + } + + @Test + @DisplayName("Test parseFromString with valid Short Form UResource string") + public void test_parseFromString_with_valid_Long_Form_UResource_string() { + UResource uResource = UResource.parseFromString("0"); + assertEquals("UResource{name='rpc', instance='response', message='null', id='0'}", uResource.toString()); + assertTrue(uResource.id().isPresent()); + assertEquals(uResource.id().get(), (short)0); + + UResource uResource2 = UResource.parseFromString("1"); + assertEquals("UResource{name='unknown', instance='null', message='null', id='1'}", uResource2.toString()); + assertTrue(uResource2.id().isPresent()); + assertEquals(uResource2.id().get(), (short)1); + } + + @Test + @DisplayName("Test parseFromString with missing instance and or message") + public void test_parseFromString_with_missing_instance_and_or_message() { + UResource uResource = UResource.parseFromString("door"); + assertEquals("UResource{name='door', instance='null', message='null', id='null'}", uResource.toString()); + assertTrue(uResource.id().isEmpty()); + + UResource uResource1 = UResource.parseFromString("door.front_left"); + assertEquals("UResource{name='door', instance='front_left', message='null', id='null'}", uResource1.toString()); + assertTrue(uResource1.id().isEmpty()); + + UResource uResource5 = UResource.parseFromString("door.front_left#Door"); + assertEquals("UResource{name='door', instance='front_left', message='Door', id='null'}", uResource5.toString()); + assertTrue(uResource5.id().isEmpty()); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 3b159f96..2169ff3e 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -26,9 +26,13 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.net.InetAddress; +import java.net.UnknownHostException; + class UriTest { @Test @@ -163,4 +167,68 @@ public void test_is_empty() { assertTrue(uri2.isEmpty()); } + @Test + @DisplayName("Test isResolved and isLongForm for valid URIs") + public void test_isResolved_and_isLongForm() throws UnknownHostException { + UUri uri = UUri.empty(); + + assertFalse(uri.isResolved()); + assertFalse(uri.isLongForm()); + + UUri uri2 = new UUri(UAuthority.local(), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + assertFalse(uri2.isResolved()); + assertTrue(uri2.isLongForm()); + + UUri uri3 = new UUri(UAuthority.local(), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + assertFalse(uri3.isResolved()); + assertTrue(uri3.isLongForm()); + + UUri uri4 = new UUri(UAuthority.local(), new UEntity("Hartley", null, (short)2), new UResource("Raise", "Salary", "Bonus", (short)1)); + assertTrue(uri4.isResolved()); + assertTrue(uri4.isLongForm()); + + + UUri uri5 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + assertFalse(uri5.isResolved()); + assertTrue(uri5.isLongForm()); + + UUri uri6 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + assertFalse(uri6.isResolved()); + assertTrue(uri6.isLongForm()); + + UUri uri7 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + assertFalse(uri7.isResolved()); + assertTrue(uri7.isLongForm()); + + + UUri uri8 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + assertFalse(uri8.isResolved()); + assertTrue(uri8.isLongForm()); + + UUri uri9 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + assertFalse(uri9.isResolved()); + assertTrue(uri9.isLongForm()); + + UUri uri10 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), new UResource("Raise", "Salary", "Bonus", (short)1)); + assertTrue(uri10.isResolved()); + assertTrue(uri10.isLongForm()); + + } + + @Test + @DisplayName("Test shortUri with valid data") + public void test_shortUri_with_valid_data() throws UnknownHostException { + UUri uri = UUri.shortUUri(null, (short)1, 2, (short)3); + assertEquals(UAuthority.local(), uri.uAuthority()); + assertEquals((short)1, uri.uEntity().id().get()); + assertEquals("2", uri.uEntity().version().get()); + assertEquals((short)3, uri.uResource().id().get()); + + UUri uri2 = UUri.shortUUri(InetAddress.getByName("192.168.1.100"), (short)1, 2, (short)3); + assertTrue(InetAddress.getByName("192.168.1.100").equals(uri2.uAuthority().address().get())); + assertEquals((short)1, uri2.uEntity().id().get()); + assertEquals("2", uri2.uEntity().version().get()); + assertEquals((short)3, uri2.uResource().id().get()); + + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java index e46adba3..48e2efbf 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java @@ -15,9 +15,9 @@ public class UriSerializerTest { @DisplayName("Test using the serializers") public void test_using_the_serializers() { final UUri uri = new UUri(UAuthority.local(), UEntity.fromName("hartley"), UResource.forRpc("raise")); - final String strUri = UriSerializer.LONG.serialize(uri); + final String strUri = UriSerializer.STRING.serialize(uri); assertEquals("/hartley//rpc.raise", strUri); - final UUri uri2 = UriSerializer.LONG.deserialize(strUri); + final UUri uri2 = UriSerializer.STRING.deserialize(strUri); assertTrue(uri.equals(uri2)); From 99eb6862107e791790f9ae83453e49534746c439 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 13 Sep 2023 21:24:23 -0400 Subject: [PATCH 29/52] Replace UriFactory with UriSerializer Also added many test cases. --- .../cloudevent/factory/CloudEventFactory.java | 1 - .../validate/CloudEventValidator.java | 11 +- .../uprotocol/uri/datamodel/UAuthority.java | 59 +-- .../eclipse/uprotocol/uri/datamodel/UUri.java | 19 +- .../uprotocol/uri/factory/UriFactory.java | 476 ------------------ .../uri/serializer/BytesUriSerializer.java | 47 +- .../uri/serializer/StringUriSerializer.java | 95 +--- .../uprotocol/uri/validator/UriValidator.java | 29 +- .../factory/CloudEventFactoryTest.java | 41 +- .../cloudevent/factory/UCloudEventTest.java | 4 +- .../CloudEventToJsonSerializerTest.java | 5 +- .../CloudEventToProtobufSerializerTest.java | 7 +- .../validate/CloudEventValidatorTest.java | 4 +- .../uprotocol/uri/datamodel/UUriTest.java | 23 +- .../serializer/BytesUriSerializerTest.java | 165 ++++++ .../StringUriSerializerTest.java} | 332 ++++-------- .../uri/serializer/UriSerializerTest.java | 26 - .../uri/validator/UriValidatorTest.java | 60 +-- .../validator/UAttributesValidatorTest.java | 14 +- 19 files changed, 399 insertions(+), 1019 deletions(-) delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java create mode 100644 src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java rename src/test/java/org/eclipse/uprotocol/uri/{factory/UriFactoryTest.java => serializer/StringUriSerializerTest.java} (77%) delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java b/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java index 29382cb7..509787b5 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java @@ -24,7 +24,6 @@ import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; import com.google.protobuf.Any; import com.google.protobuf.Empty; import com.google.rpc.Code; diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java index a883e9a8..e96b9203 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java @@ -26,7 +26,8 @@ import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; + import com.google.rpc.Code; import com.google.rpc.Status; import io.cloudevents.CloudEvent; @@ -147,7 +148,7 @@ public ValidationResult validateSink(CloudEvent cloudEvent) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateUEntityUri(String uri) { - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); return validateUEntityUri(Uri); } @@ -170,7 +171,7 @@ public static ValidationResult validateUEntityUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateTopicUri(String uri) { - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); return validateTopicUri(Uri); } @@ -201,7 +202,7 @@ public static ValidationResult validateTopicUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcTopicUri(String uri) { - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); return validateRpcTopicUri(Uri); } @@ -229,7 +230,7 @@ public static ValidationResult validateRpcTopicUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcMethod(String uri) { - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); ValidationResult validationResult = validateUEntityUri(Uri); if (validationResult.isFailure()){ return ValidationResult.failure(String.format("Invalid RPC method uri. %s", validationResult.getMessage())); diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 03732d33..a82ce94e 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -34,7 +34,7 @@ * An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ public class UAuthority { - private final static UAuthority EMPTY = new UAuthority(null, null, null, false); + private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); /** * A device is a logical independent representation of a service bus in different execution environments.
@@ -60,6 +60,12 @@ public class UAuthority { */ private final InetAddress address; + /** + * Indicates that the UUri contains both address and name and + * the name is not the string version of the IP address + */ + private final boolean markedResolved; + /** * Constructor. @@ -68,12 +74,14 @@ public class UAuthority { * @param address The device IP address. * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. * @param addressName Indicates if the device name is an IP address + * @param markedResolved Indicates if the UAuthority contains both address and names meaning the UAuthority is resolved. */ - private UAuthority(String device, String domain, InetAddress address, boolean markedRemote) { + private UAuthority(String device, String domain, InetAddress address, boolean markedRemote, boolean markedResolved) { this.device = device == null ? null : device.toLowerCase(); this.domain = domain == null ? null : domain.toLowerCase(); this.address = address; this.markedRemote = markedRemote; + this.markedResolved = markedResolved; } @@ -118,12 +126,15 @@ public static UAuthority remote(InetAddress address) { */ public static UAuthority remote(String device, String domain, InetAddress address) { InetAddress addr = address; + boolean markedResolved = device != null && address != null; + // Try and set the address based on device name if the name is the string - // representation of an ip address + // representation of an ip address. For this we need to mark it explicitly not resolved if ( (device != null) && (addr == null) ) { try { if (InetAddressValidator.getInstance().isValid(device)) { addr = InetAddress.getByName(device); + markedResolved = false; } else { addr = null; } @@ -132,7 +143,7 @@ public static UAuthority remote(String device, String domain, InetAddress addres } } - return new UAuthority(device, domain, addr, true); + return new UAuthority(device, domain, addr, true, markedResolved); } /** @@ -154,7 +165,7 @@ public boolean isRemote() { * @return returns true if this authority is local, meaning does not contain a device or a domain. */ public boolean isLocal() { - return domain().isEmpty() && device().isEmpty() && address().isEmpty(); + return domain().isEmpty() && device().isEmpty(); } /** @@ -187,12 +198,13 @@ public boolean isMarkedRemote() { } /** - * Returns true if UAuthority is local or contains both address and names if the name was not populated with the - * string representation of the address - * @return Returns true if UAuthority contains both address and names meaning the UAuthority is resolved. + * Returns true if the UAuthority was tagged as resolved meaning the name and address are present and + * the name is NOT the string version of the IP address. *NOTE:* there is no way to know if the address is + * in fact a valid DNS address for the device+domain name so we will assume it is. + * @return Returns true if UAuthority contains both address and name. */ public boolean isResolved() { - return isLocal() || (address().isPresent() && device().isPresent()); + return markedResolved; } /** @@ -212,12 +224,13 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; UAuthority that = (UAuthority) o; return markedRemote == that.markedRemote && Objects.equals(device, that.device) - && Objects.equals(domain, that.domain) && Objects.equals(address, that.address) ; + && Objects.equals(domain, that.domain) && Objects.equals(address, that.address) + && markedResolved == that.markedResolved ; } @Override public int hashCode() { - return Objects.hash(device, domain, address, markedRemote); + return Objects.hash(device, domain, address, markedRemote, markedResolved); } @Override @@ -230,28 +243,4 @@ public String toString() { '}'; } - /** - * The type of address used for Micro URI. - */ - public enum AddressType { - LOCAL(0), - IPv4(1), - IPv6(2); - - private final int value; - - private AddressType(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - public static Optional from(int value) { - return Arrays.stream(AddressType.values()) - .filter(p -> p.getValue() == value) - .findAny(); - } - } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 000c5be5..4d7aadbf 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -68,20 +68,15 @@ public UUri(UAuthority uAuthority, UEntity uEntity, String uResource) { } /** - * Create a Short UUri using only IDs containing only IDs - * @param uAuthority The internet address of the device or nyll if it is local - * @param ueId The id of the ue - * @param version The version of the ue - * @param uResource The id of the resource - * @return Returns a UUri containing only IDs + * Create a RPC Response UUri passing the Authority and Entity information + * @param uAuthority The Authority represents the deployment location of a specific Software Entity. + * @param uEntity The SW entity information + * @return Returns a UUri of a constructed RPC Response */ - public static UUri shortUUri(InetAddress address, Short ueId, Integer version, Short uResource) { - Objects.requireNonNull(ueId, "Short Uri must have an ueId"); - Objects.requireNonNull(version, "Short Uri must have a version"); - Objects.requireNonNull(uResource, "Short Uri must have an uResource"); - return new UUri(address == null ? UAuthority.local() : UAuthority.remote(address), - UEntity.fromId(String.valueOf(version), ueId), UResource.fromId(uResource)); + public static UUri rpcResponse(UAuthority uAuthority, UEntity uEntity) { + return new UUri(uAuthority, uEntity, UResource.response()); } + /** * Static factory method for creating an empty uri, to avoid working with null
diff --git a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java b/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java deleted file mode 100644 index da819a1b..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/factory/UriFactory.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.factory; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.datamodel.UAuthority.AddressType; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * UUri Factory used to build different types of UUri (long, short, micro), and UUri objects themselves - * for the various use cases found in uProtocol specifications. - * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc - */ -public interface UriFactory { - - static final int LOCAL_MICRO_URI_LENGTH = 8; // local micro URI length - - static final int IPV4_MICRO_URI_LENGTH = 12; // IPv4 micro URI length - - static final int IPV6_MICRO_URI_LENGTH = 24; // IPv6 micro Uri length - - - /** - * Build a Long-URI string from the separate parts of an URI. - * - * @param Uri The URI data object. - * @return Returns the uProtocol URI string from an URI data object - * that can be used as a sink or a source in a uProtocol publish communication. - */ - static String buildUProtocolUri(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { - return new String(); - } - - StringBuilder sb = new StringBuilder(); - - sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), false)); - - if (Uri.uAuthority().isMarkedRemote()) { - sb.append("/"); - } - - if (Uri.uEntity().isEmpty()) { - return sb.toString(); - } - - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), false)); - - sb.append(buildResourcePartOfUri(Uri.uResource(), false)); - - return sb.toString().replaceAll("/+$", ""); - } - - /** - * Build a Long-Uri string using the separate parts of an URI. - * of an URI. - * - * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. - * @param uEntity The Software Entity in the role of a service or in the role of an application. - * @param uResource The resource is something that is manipulated by a service such as a Door. - * - * @return Returns the uProtocol URI string from an URI data object - * that can be used as a sink or a source in a uProtocol publish communication. - */ - static String buildUProtocolUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { - return buildUProtocolUri(new UUri(uAuthority, uEntity, uResource)); - } - - - /** - * Build a Short-Uri string from a UUri object - * - * @param Uri The URI data object. - * @return Returns the short form uProtocol URI string from an URI data object - */ - static String buildUProtocolShortUri(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { - return new String(); - } - - StringBuilder sb = new StringBuilder(); - - sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), true)); - - if (Uri.uAuthority().isMarkedRemote()) { - sb.append("/"); - } - - if (Uri.uEntity().id().isEmpty()) { - return sb.toString(); - } - - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), true)); - - sb.append(buildResourcePartOfUri(Uri.uResource(), true)); - - return sb.toString().replaceAll("/+$", ""); - } - - /** - * Build a Short-Uri string using the separate parts of an URI. - * of an URI. - * - * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. - * @param uEntity The Software Entity in the role of a service or in the role of an application. - * @param uResource The resource is something that is manipulated by a service such as a Door. - * - * @return Returns the uProtocol URI string from an URI data object - * that can be used as a sink or a source in a uProtocol publish communication. - */ - static String buildUProtocolShortUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { - return buildUProtocolShortUri(new UUri(uAuthority, uEntity, uResource)); - } - - /** - * Build a Micro-URI byte[] using a passed UUri object - * - * @param Uri The URI data object. - * @return Returns the short form uProtocol URI string from an URI data object - */ - static byte[] buildUProtocolMicroUri(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { - return new byte[0]; - } - - Optional maybeAddress = Uri.uAuthority().address(); - Optional maybeUeId = Uri.uEntity().id(); - Optional maybeUResourceId = Uri.uResource().id(); - if (!maybeUeId.isPresent() || !maybeUResourceId.isPresent()) { - return new byte[0]; - } - - // Remote Uri but the address is missing - if (!maybeAddress.isPresent() && Uri.uAuthority().isRemote()) { - return new byte[0]; - } - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - // UP_VERSION - os.write(0x1); - - // TYPE - if (Uri.uAuthority().isLocal()) { - os.write(0x0); - } else { - os.write(maybeAddress.get() instanceof Inet4Address ? 1 : 2); - } - - // URESOURCE_ID - os.write(maybeUResourceId.get()>>8); - os.write(maybeUResourceId.get()); - - // UAUTHORITY_ADDRESS - if (!Uri.uAuthority().isLocal()) { - try { - os.write(maybeAddress.get().getAddress()); - } catch (IOException e) { - return new byte[0]; - } - } - - // UENTITY_ID - os.write(maybeUeId.get()>>8); - os.write(maybeUeId.get()); - - // UE_VERSION - String version = Uri.uEntity().version().orElse(""); - os.write(version.isEmpty() ? (byte)0 : Integer.parseInt(version.split("\\.")[0])); - - // UNUSED - os.write((byte)0); - - return os.toByteArray(); - - } - - /** - * Create the uProtocol URI string for the source or sink of the CloudEvent that represents an RPC request. - * Use this to generate the URI for the software entity who originated the RPC call. - * As specified in SDV-202 Request for the source and SDV-202 Response for the sink. - * - * @param uAuthority The uAuthority of the software entity requesting the RPC. - * @param uEntitySource The software entity requesting the RPC. - * @return Returns the uProtocol URI string that can be used in a CloudEvent representing the application making an RPC call to a service. - */ - static String buildUriForRpc(UAuthority uAuthority, - UEntity uEntitySource) { - StringBuilder sb = new StringBuilder(); - - sb.append(buildAuthorityPartOfUri(uAuthority, false)); - if (uAuthority.isMarkedRemote()) { - sb.append("/"); - } - sb.append(buildSoftwareEntityPartOfUri(uEntitySource, false)); - sb.append("/"); - sb.append(UResource.response().nameWithInstance()); - - return sb.toString(); - } - - /** - * Create the uProtocol URI string for the sink of the CloudEvent that represents an RPC request - * or the source of the CloudEvent that represents an RPC response. - * @param uAuthority The uAuthority of the software entity service accepting the RPC. - * @param uEntity The software entity service accepting the RPC. - * @param methodName The name of the RPC method on the service such as UpdateDoor. - * @return Returns Returns the uProtocol URI string for the sink of the CloudEvent that represents - * an RPC request or the source of the CloudEvent that represents an RPC response for RPC scenarios. - */ - static String buildMethodUri(UAuthority uAuthority, UEntity uEntity, String methodName) { - StringBuilder sb = new StringBuilder(); - - sb.append(buildAuthorityPartOfUri(uAuthority, false)); - if (uAuthority.isMarkedRemote()) { - sb.append("/"); - } - sb.append(buildSoftwareEntityPartOfUri(uEntity, false)); - - sb.append(buildResourcePartOfUri(UResource.forRpc(methodName), false)); - - return sb.toString(); - } - - private static String buildResourcePartOfUri(UResource uResource, boolean shortUri) { - if (uResource.isEmpty()) { - return ""; - } - StringBuilder sb = new StringBuilder("/"); - if (shortUri) { - uResource.id().ifPresent(sb::append); - } else { - sb.append(uResource.name()); - uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); - uResource.message().ifPresent(message -> sb.append("#").append(message)); - } - - return sb.toString(); - } - - /** - * Create the service part of the uProtocol URI from an software entity object. - * @param use Software Entity representing a service or an application. - */ - private static String buildSoftwareEntityPartOfUri(UEntity use, boolean shortUri) { - StringBuilder sb = new StringBuilder(shortUri? use.id().get().toString() : use.name().trim()); - sb.append("/"); - use.version().ifPresent(sb::append); - - return sb.toString(); - } - - - /** - * Create the authority part of the uProtocol URI from an authority object. - * @param Authority represents the deployment location of a specific Software Entity in the Ultiverse. - * @return Returns the String representation of the Authority in the uProtocol URI. - */ - private static String buildAuthorityPartOfUri(UAuthority Authority, boolean shortUri) { - if (Authority.isLocal()) { - return "/"; - } - StringBuilder partialURI = new StringBuilder("//"); - if (shortUri) { - final Optional maybeAddress = Authority.address(); - if (maybeAddress.isPresent()) { - partialURI.append(maybeAddress.get().getHostAddress()); - } - return partialURI.toString(); - } - final Optional maybeDevice = Authority.device(); - final Optional maybeDomain = Authority.domain(); - - if (maybeDevice.isPresent()) { - partialURI.append(maybeDevice.get()); - maybeDomain.ifPresent(domain -> partialURI.append(".")); - } - maybeDomain.ifPresent(partialURI::append); - - return partialURI.toString(); - } - - /** - * Create an UUri data object from a uProtocol string either long or short format. - * @param uProtocolUri A short or long format uProtocol URI. - * @return Returns an UUri data object. - */ - static UUri parseFromUri(String uProtocolUri) { - if (uProtocolUri == null || uProtocolUri.isBlank()) { - return UUri.empty(); - } - - String uri = uProtocolUri.contains(":") ? uProtocolUri.substring(uProtocolUri.indexOf(":")+1) : uProtocolUri - .replace('\\', '/'); - - boolean isLocal = !uri.startsWith("//"); - - final String[] uriParts = uri.split("/"); - final int numberOfPartsInUri = uriParts.length; - - if(numberOfPartsInUri == 0 || numberOfPartsInUri == 1) { - return isLocal ? UUri.empty() : - new UUri(UAuthority.remote("", ""), UEntity.empty(), UResource.empty()); - } - - String useName; - String useVersion = ""; - - UResource uResource; - - UAuthority uAuthority; - if(isLocal) { - uAuthority = UAuthority.local(); - useName = uriParts[1]; - if (numberOfPartsInUri > 2) { - useVersion = uriParts[2]; - - uResource = numberOfPartsInUri > 3 ? buildResource(uriParts[3]) : UResource.empty(); - - } else { - uResource = UResource.empty(); - } - } else { - String[] authorityParts = uriParts[2].split("\\."); - String device = authorityParts[0]; - String domain = ""; - if (authorityParts.length > 1) { - domain = Arrays.stream(authorityParts) - .skip(1) - .collect(Collectors.joining(".")); - } - uAuthority = UAuthority.remote(device, domain); - - if (uriParts.length > 3) { - useName = uriParts[3]; - if (numberOfPartsInUri > 4) { - useVersion = uriParts[4]; - - uResource = numberOfPartsInUri > 5 ? buildResource(uriParts[5]) : UResource.empty(); - - } else { - uResource = UResource.empty(); - } - } else { - return new UUri(uAuthority, UEntity.empty(), UResource.empty()); - } - - } - - // Try and fetch the uE ID in the name portion of the string - Short maybeUeId = null; - if (!useName.isEmpty()) { - try { - maybeUeId = Short.parseShort(useName); - } catch (NumberFormatException e) { - maybeUeId = null; - - } - } - return new UUri(uAuthority, (maybeUeId != null) ? UEntity.fromId(useVersion, maybeUeId) : - new UEntity(useName, useVersion, maybeUeId), uResource); - } - - private static UResource buildResource(String resourceString) { - String[] parts = resourceString.split("#"); - String nameAndInstance = parts[0]; - - // Try and fetch the resource ID if there is one (short form) - Short maybeId = null; - try { - maybeId = Short.parseShort(nameAndInstance); - } catch (NumberFormatException e) { - maybeId = null; - - } - - if (maybeId != null) { - return UResource.fromId(maybeId); - } - - String[] nameAndInstanceParts = nameAndInstance.split("\\."); - String resourceName = nameAndInstanceParts[0]; - String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; - String resourceMessage = parts.length > 1 ? parts[1] : null; - return new UResource(resourceName, resourceInstance, resourceMessage); - } - - - /** - * Create an URI data object from a uProtocol micro URI. - * @param microUri A byte[] uProtocol micro URI. - * @return Returns an URI data object. - */ - static UUri parseFromMicroUri(byte[] microUri) { - if (microUri == null || microUri.length < UriFactory.LOCAL_MICRO_URI_LENGTH ) { - return UUri.empty(); - } - - // Need to be version 1 - if (microUri[0] != 0x1) { - return UUri.empty(); - } - - int uResourceId = ((microUri[2] & 0xFF) << 8) | (microUri[3] & 0xFF); - - Optional maybeAddress = Optional.empty(); - - Optional type = AddressType.from(microUri[1]); - - // Validate Type is found - if (!type.isPresent()) { - return UUri.empty(); - } - - // Validate that the microUri is the correct length for the type - if (type.get() == AddressType.LOCAL && microUri.length != UriFactory.LOCAL_MICRO_URI_LENGTH) { - return UUri.empty(); - } - else if (type.get() == AddressType.IPv4 && microUri.length != UriFactory.IPV4_MICRO_URI_LENGTH) { - return UUri.empty(); - } - else if (type.get() == AddressType.IPv6 && microUri.length != UriFactory.IPV6_MICRO_URI_LENGTH) { - return UUri.empty(); - } - - int index = 4; - if (!(type.get() == AddressType.LOCAL)) { - try { - maybeAddress = Optional.of(InetAddress.getByAddress( - Arrays.copyOfRange(microUri, index, (type.get() == AddressType.IPv4) ? 8 : 20))); - } catch (Exception e) { - maybeAddress = Optional.empty(); - } - index += type.get() == AddressType.IPv4 ? 4 : 16; - } - - // UENTITY_ID - int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - - // UE_VERSION - int uiVersion = microUri[index++]; - - return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), - UEntity.fromId(String.valueOf(uiVersion), (short)ueId), - UResource.fromId((short)uResourceId)); - } - -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java index 50c812c1..8f0f5860 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java @@ -25,7 +25,6 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.datamodel.UAuthority.AddressType; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -47,6 +46,32 @@ public class BytesUriSerializer implements UriSerializer { static final int IPV6_MICRO_URI_LENGTH = 24; // IPv6 micro Uri length + static final byte UP_VERSION = 0x1; // UP version + + /** + * The type of address used for Micro URI. + */ + private enum AddressType { + LOCAL(0), + IPv4(1), + IPv6(2); + + private final int value; + + private AddressType(int value) { + this.value = value; + } + + public byte getValue() { + return (byte)value; + } + + public static Optional from(int value) { + return Arrays.stream(AddressType.values()) + .filter(p -> p.getValue() == value) + .findAny(); + } + } /** * Serialize a UUri into a byte[] following the Micro-URI specifications @@ -63,24 +88,22 @@ public byte[] serialize(UUri Uri) { Optional maybeAddress = Uri.uAuthority().address(); Optional maybeUeId = Uri.uEntity().id(); Optional maybeUResourceId = Uri.uResource().id(); - if (!maybeUeId.isPresent() || !maybeUResourceId.isPresent()) { - return new byte[0]; - } - // Remote Uri but the address is missing - if (!maybeAddress.isPresent() && Uri.uAuthority().isRemote()) { + // Cannot create a micro URI without UResource ID or uEntity ID + if (!maybeUResourceId.isPresent() || !maybeUeId.isPresent()) { return new byte[0]; } - + ByteArrayOutputStream os = new ByteArrayOutputStream(); // UP_VERSION - os.write(0x1); + os.write(UP_VERSION); // TYPE - if (Uri.uAuthority().isLocal()) { - os.write(0x0); + if (maybeAddress.isPresent()) { + os.write(maybeAddress.get() instanceof Inet4Address ? + AddressType.IPv4.getValue() : AddressType.IPv6.getValue()); } else { - os.write(maybeAddress.get() instanceof Inet4Address ? 1 : 2); + os.write(AddressType.LOCAL.getValue()); } // URESOURCE_ID @@ -88,7 +111,7 @@ public byte[] serialize(UUri Uri) { os.write(maybeUResourceId.get()); // UAUTHORITY_ADDRESS - if (!Uri.uAuthority().isLocal()) { + if (maybeAddress.isPresent()) { try { os.write(maybeAddress.get().getAddress()); } catch (IOException e) { diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java index 1d6ee16f..63122308 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java @@ -37,7 +37,7 @@ public class StringUriSerializer implements UriSerializer { /** - * Serialize the UUri object into a String containing either long or short form. + * Serialize the UUri object Into a string in Long Form. * * @param Uri The URI data object. * @return Returns the uProtocol URI string from an URI data object @@ -51,7 +51,7 @@ public String serialize(UUri Uri) { StringBuilder sb = new StringBuilder(); - sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), false)); + sb.append(buildAuthorityPartOfUri(Uri.uAuthority())); if (Uri.uAuthority().isMarkedRemote()) { sb.append("/"); @@ -61,75 +61,21 @@ public String serialize(UUri Uri) { return sb.toString(); } - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), false)); + sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity())); - sb.append(buildResourcePartOfUri(Uri.uResource(), false)); + sb.append(buildResourcePartOfUri(Uri.uResource())); return sb.toString().replaceAll("/+$", ""); } - - - /** - * Build a Short-Uri string from a UUri object - * - * @param Uri The URI data object. - * @return Returns the short form uProtocol URI string from an URI data object - */ - static String toShortUri(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { - return new String(); - } - - StringBuilder sb = new StringBuilder(); - - sb.append(buildAuthorityPartOfUri(Uri.uAuthority(), true)); - - if (Uri.uAuthority().isMarkedRemote()) { - sb.append("/"); - } - - if (Uri.uEntity().id().isEmpty()) { - return sb.toString(); - } - - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity(), true)); - - sb.append(buildResourcePartOfUri(Uri.uResource(), true)); - - return sb.toString().replaceAll("/+$", ""); - } - - /** - * Build a Short-Uri string using the separate parts of an URI. - * of an URI. - * - * @param uAuthority The Authority represents the deployment location of a specific Software Entity in the Ultiverse. - * @param uEntity The Software Entity in the role of a service or in the role of an application. - * @param uResource The resource is something that is manipulated by a service such as a Door. - * - * @return Returns the uProtocol URI string from an URI data object - * that can be used as a sink or a source in a uProtocol publish communication. - */ - static String toShortUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { - return toShortUri(new UUri(uAuthority, uEntity, uResource)); - } - - - - - private static String buildResourcePartOfUri(UResource uResource, boolean shortUri) { + private static String buildResourcePartOfUri(UResource uResource) { if (uResource.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder("/"); - if (shortUri) { - uResource.id().ifPresent(sb::append); - } else { - sb.append(uResource.name()); - uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); - uResource.message().ifPresent(message -> sb.append("#").append(message)); - } + sb.append(uResource.name()); + uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); + uResource.message().ifPresent(message -> sb.append("#").append(message)); return sb.toString(); } @@ -138,8 +84,8 @@ private static String buildResourcePartOfUri(UResource uResource, boolean shortU * Create the service part of the uProtocol URI from an software entity object. * @param use Software Entity representing a service or an application. */ - private static String buildSoftwareEntityPartOfUri(UEntity use, boolean shortUri) { - StringBuilder sb = new StringBuilder(shortUri? use.id().get().toString() : use.name().trim()); + private static String buildSoftwareEntityPartOfUri(UEntity use) { + StringBuilder sb = new StringBuilder(use.name().trim()); sb.append("/"); use.version().ifPresent(sb::append); @@ -152,18 +98,11 @@ private static String buildSoftwareEntityPartOfUri(UEntity use, boolean shortUri * @param Authority represents the deployment location of a specific Software Entity in the Ultiverse. * @return Returns the String representation of the Authority in the uProtocol URI. */ - private static String buildAuthorityPartOfUri(UAuthority Authority, boolean shortUri) { + private static String buildAuthorityPartOfUri(UAuthority Authority) { if (Authority.isLocal()) { return "/"; } StringBuilder partialURI = new StringBuilder("//"); - if (shortUri) { - final Optional maybeAddress = Authority.address(); - if (maybeAddress.isPresent()) { - partialURI.append(maybeAddress.get().getHostAddress()); - } - return partialURI.toString(); - } final Optional maybeDevice = Authority.device(); final Optional maybeDomain = Authority.domain(); @@ -244,17 +183,7 @@ public UUri deserialize(String uProtocolUri) { } - // Try and fetch the uE ID in the name portion of the string - Short maybeUeId = null; - if (!useName.isEmpty()) { - try { - maybeUeId = Short.parseShort(useName); - } catch (NumberFormatException e) { - maybeUeId = null; - - } - } - return new UUri(uAuthority, new UEntity(useName, useVersion.isBlank()? null : useVersion, maybeUeId), uResource); + return new UUri(uAuthority, new UEntity(useName, useVersion.isBlank() ? null : useVersion), uResource); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 62f56554..4b3ea165 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -2,7 +2,7 @@ import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; @@ -72,33 +72,8 @@ public static UStatus validateRpcResponse(UUri uri) { * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validateLongUUri(String uri) { - final UUri uUri = UriFactory.parseFromUri(uri); + final UUri uUri = UriSerializer.STRING.deserialize(uri); return validate(uUri); } - /** - * Validate that a passed shortUri and microUri are the same. We cannot validate long to short - * without the mapping of names to ids. - * @param shortUri Short form URI - * @param microUri Micro form URI - * @return Returns the UStatus containing a success or a failure with the error message. - */ - public static UStatus validateEqualsShortMicroUri(String shortUri, byte[] microUri) { - final UUri uUri = UriFactory.parseFromUri(shortUri); - final UUri uUriMicro = UriFactory.parseFromMicroUri(microUri); - - if (uUri.isEmpty()) { - return UStatus.failed("Short Uri is invalid.", Code.INVALID_ARGUMENT); - } - if (uUriMicro.isEmpty()) { - return UStatus.failed("Micro Uri is invalid.", Code.INVALID_ARGUMENT); - } - - if (!uUri.equals(uUriMicro)) { - String failure = String.format("Short URI %s and Micro Uri %s are not equal.", uUri.toString(), uUriMicro.toString()); - return UStatus.failed(failure, Code.INVALID_ARGUMENT); - } - return UStatus.ok(); - } - } diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index f3bbe425..2175e6b5 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -27,7 +27,8 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; + import com.google.protobuf.Any; import com.google.rpc.Code; import io.cloudevents.CloudEvent; @@ -52,7 +53,7 @@ public void test_create_base_cloud_event() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -94,7 +95,7 @@ public void test_create_base_cloud_event_with_datacontenttype_and_schema() { UEntity use = UEntity.fromName("body.access"); UUri ultifiUri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(ultifiUri); + String source = UriSerializer.STRING.serialize(ultifiUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -142,7 +143,7 @@ public void test_create_base_cloud_event_without_attributes() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -179,7 +180,7 @@ public void test_create_publish_cloud_event() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -213,12 +214,12 @@ public void test_create_notification_cloud_event() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // sink UEntity sinkUse = UEntity.fromName("petapp"); UUri sinkUri = new UUri(UAuthority.remote("com.gm.bo", "bo"), sinkUse, "OK"); - String sink = UriFactory.buildUProtocolUri(sinkUri); + String sink = UriSerializer.STRING.serialize(sinkUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -255,13 +256,13 @@ public void test_create_request_cloud_event_from_local_use() { // Uri for the application requesting the RPC UEntity sourceUse = UEntity.fromName("petapp"); - String applicationUriForRPC = UriFactory.buildUriForRpc(UAuthority.local(), sourceUse); + String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriFactory.buildUProtocolUri(methodUri); + String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -301,14 +302,14 @@ public void test_create_request_cloud_event_from_remote_use() { // Uri for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); UEntity sourceUse = new UEntity("petapp", "1"); - String applicationUriForRPC = UriFactory.buildUriForRpc(sourceUseAuthority, sourceUse); + String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriFactory.buildUProtocolUri(methodUri); + String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -347,13 +348,13 @@ public void test_create_response_cloud_event_originating_from_local_use() { // Uri for the application requesting the RPC UEntity sourceUse = new UEntity("petapp", "1"); - String applicationUriForRPC = UriFactory.buildUriForRpc(UAuthority.local(), sourceUse); + String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriFactory.buildUProtocolUri(methodUri); + String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -393,14 +394,15 @@ public void test_create_response_cloud_event_originating_from_remote_use() { // Uri for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); UEntity sourceUse = UEntity.fromName("petapp"); - String applicationUriForRPC = UriFactory.buildUriForRpc(sourceUseAuthority, sourceUse); + + String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriFactory.buildUProtocolUri(methodUri); + String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -440,13 +442,13 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use // Uri for the application requesting the RPC UEntity sourceUse = new UEntity("petapp", "1"); - String applicationUriForRPC = UriFactory.buildUriForRpc(UAuthority.local(), sourceUse); + String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriFactory.buildUProtocolUri(methodUri); + String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -487,14 +489,15 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us // Uri for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); UEntity sourceUse = UEntity.fromName("petapp"); - String applicationUriForRPC = UriFactory.buildUriForRpc(sourceUseAuthority, sourceUse); + + String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriFactory.buildUProtocolUri(methodUri); + String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java index 6b1149b8..418790fa 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java @@ -27,7 +27,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import com.google.protobuf.Any; import com.google.protobuf.InvalidProtocolBufferException; @@ -683,7 +683,7 @@ private CloudEventBuilder buildBaseCloudEventBuilderForTest() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java index 3e6f4b91..0d4a98dc 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java @@ -29,7 +29,8 @@ import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; + import com.google.protobuf.Any; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; @@ -167,7 +168,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java index 5a06c53b..35cde75e 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java @@ -29,7 +29,8 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; + import com.google.protobuf.Any; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; @@ -57,7 +58,7 @@ public void test_serialize_and_desirialize_cloud_event_to_protobuf() { // build the source UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("Door", "front_left")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -147,7 +148,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index b2c3d58a..6260297b 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -28,7 +28,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import com.google.protobuf.Any; import com.google.rpc.Code; @@ -1073,7 +1073,7 @@ private CloudEventBuilder buildBaseCloudEventBuilderForTest() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + String source = UriSerializer.STRING.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 2169ff3e..36923122 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -187,6 +187,9 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertTrue(uri4.isResolved()); assertTrue(uri4.isLongForm()); + UUri uri11 = new UUri(UAuthority.local(), new UEntity("Hartley", null, (short)2), UResource.forRpc("Raise")); + assertFalse(uri11.isResolved()); + assertTrue(uri11.isLongForm()); UUri uri5 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); assertFalse(uri5.isResolved()); @@ -213,22 +216,10 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertTrue(uri10.isResolved()); assertTrue(uri10.isLongForm()); - } - - @Test - @DisplayName("Test shortUri with valid data") - public void test_shortUri_with_valid_data() throws UnknownHostException { - UUri uri = UUri.shortUUri(null, (short)1, 2, (short)3); - assertEquals(UAuthority.local(), uri.uAuthority()); - assertEquals((short)1, uri.uEntity().id().get()); - assertEquals("2", uri.uEntity().version().get()); - assertEquals((short)3, uri.uResource().id().get()); - - UUri uri2 = UUri.shortUUri(InetAddress.getByName("192.168.1.100"), (short)1, 2, (short)3); - assertTrue(InetAddress.getByName("192.168.1.100").equals(uri2.uAuthority().address().get())); - assertEquals((short)1, uri2.uEntity().id().get()); - assertEquals("2", uri2.uEntity().version().get()); - assertEquals((short)3, uri2.uResource().id().get()); + UUri uri12 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), UResource.fromId((short)2)); + assertFalse(uri12.isResolved()); + assertFalse(uri12.isLongForm()); } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java new file mode 100644 index 00000000..a554e886 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java @@ -0,0 +1,165 @@ +package org.eclipse.uprotocol.uri.serializer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class BytesUriSerializerTest { + + @Test + @DisplayName("Test serialize and deserialize empty content") + public void test_empty() { + UUri uri = UUri.empty(); + byte[] bytes = UriSerializer.BYTES.serialize(uri); + + assertEquals(bytes.length, 0); + + UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + assertTrue(uri2.isEmpty()); + } + + @Test + @DisplayName("Test serialize and deserialize null content") + public void test_null() { + byte[] bytes = UriSerializer.BYTES.serialize(null); + + assertEquals(bytes.length, 0); + + UUri uri2 = UriSerializer.BYTES.deserialize(null); + assertTrue(uri2.isEmpty()); + } + + @Test + @DisplayName("Test happy path Byte serialization of local UUri") + public void test_serialize_uri() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = UEntity.fromId("1", (short)2); + UResource uResource = UResource.fromId((short)3); + + UUri uri = new UUri(uAuthority, use, uResource); + + byte[] bytes = UriSerializer.BYTES.serialize(uri); + UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + + assertEquals(uri, uri2); + } + + + @Test + @DisplayName("Test serialize invalid UUris") + public void test_serialize_invalid_uuris() throws UnknownHostException { + UUri uri = new UUri(UAuthority.local(), UEntity.fromId("", (short)1), UResource.empty()); + byte[] bytes = UriSerializer.BYTES.serialize(uri); + assertEquals(bytes.length, 0); + + UUri uri2 = new UUri(UAuthority.local(), new UEntity("", ""), UResource.forRpc("", (short)1)); + byte[] bytes2 = UriSerializer.BYTES.serialize(uri2); + assertEquals(bytes2.length, 0); + + UUri uri3 = new UUri(UAuthority.remote("null", "null"), new UEntity("", ""), UResource.forRpc("", (short)1)); + byte[] bytes3 = UriSerializer.BYTES.serialize(uri3); + assertEquals(bytes3.length, 0); + + UUri uri4 = new UUri(UAuthority.remote("vcu", "vin", null), new UEntity("", ""), UResource.forRpc("", (short)1)); + byte[] bytes4 = UriSerializer.BYTES.serialize(uri4); + assertEquals(bytes4.length, 0); + } + + @Test + @DisplayName("Test serialize and deserialize IPv4 UUris") + public void test_serialize_ipv4_uri() throws UnknownHostException { + UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("192.168.1.100")); + UEntity use = UEntity.fromId("1", (short)2); + UResource uResource = UResource.fromId((short)3); + UUri uri = new UUri(uAuthority, use, uResource); + + byte[] bytes = UriSerializer.BYTES.serialize(uri); + UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + assertEquals(uri, uri2); + } + + @Test + @DisplayName("Test serialize and deserialize IPv6 UUris") + public void test_serialize_ipv6_uri() throws UnknownHostException { + UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); + UEntity use = UEntity.fromId("1", (short)2); + UResource uResource = UResource.fromId((short)3); + UUri uri = new UUri(uAuthority, use, uResource); + + byte[] bytes = UriSerializer.BYTES.serialize(uri); + UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + assertEquals(uri, uri2); + } + + @Test + @DisplayName("Test deserialize with missing information") + public void test_deserialize_with_missing_information() throws UnknownHostException { + UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); + UEntity use = UEntity.fromId("1", (short)2); + UResource uResource = UResource.fromId((short)3); + UUri uri = new UUri(uAuthority, use, uResource); + byte[] bytes = UriSerializer.BYTES.serialize(uri); + + // invalid version + byte[] byte1 = Arrays.copyOf(bytes, bytes.length); + byte1[0] = 0x0; + UUri uri1 = UriSerializer.BYTES.deserialize(byte1); + assertTrue(uri1.isEmpty()); + + // Invalid type + byte[] byte2 = Arrays.copyOf(bytes, bytes.length); + byte2[1] = Byte.MAX_VALUE; + UUri uri2 = UriSerializer.BYTES.deserialize(byte2); + assertTrue(uri2.isEmpty()); + + // Wrong size (local) + byte[] byte3 = new byte[] {0x1, 0x0, 0x0, 0x0}; + UUri uri3 = UriSerializer.BYTES.deserialize(byte3); + assertTrue(uri3.isEmpty()); + + // Wrong size (ipv4) + byte[] byte4 = new byte[] {0x1, 0x1, 0x0, 0x0}; + UUri uri4 = UriSerializer.BYTES.deserialize(byte4); + assertTrue(uri4.isEmpty()); + + // Wrong size (ipv6) + byte[] byte5 = new byte[] {0x1, 0x1, 0x0, 0x0}; + UUri uri5 = UriSerializer.BYTES.deserialize(byte5); + assertTrue(uri5.isEmpty()); + + // Right local size (local) + byte[] byte6 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri6 = UriSerializer.BYTES.deserialize(byte6); + assertFalse(uri6.isEmpty()); + + // IPv4 type local size + byte[] byte7 = new byte[] {0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri7 = UriSerializer.BYTES.deserialize(byte7); + assertTrue(uri7.isEmpty()); + + // IPv6 type local size + byte[] byte8 = new byte[] {0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri8 = UriSerializer.BYTES.deserialize(byte8); + assertTrue(uri8.isEmpty()); + + + // Local type but too large + byte[] byte9 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri9 = UriSerializer.BYTES.deserialize(byte9); + assertTrue(uri9.isEmpty()); + + } + + +} diff --git a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java similarity index 77% rename from src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java rename to src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java index b3d0e598..31f6e232 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/factory/UriFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java @@ -1,47 +1,31 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.factory; +package org.eclipse.uprotocol.uri.serializer; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.datamodel.UAuthority.AddressType; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; -class UriFactoryTest { +public class StringUriSerializerTest { @Test + @DisplayName("Test using the serializers") + public void test_using_the_serializers() { + final UUri uri = new UUri(UAuthority.local(), UEntity.fromName("hartley"), UResource.forRpc("raise")); + final String strUri = UriSerializer.STRING.serialize(uri); + assertEquals("/hartley//rpc.raise", strUri); + final UUri uri2 = UriSerializer.STRING.deserialize(strUri); + assertTrue(uri.equals(uri2)); + } + + @Test @DisplayName("Test parse uProtocol uri that is null") public void test_parse_protocol_uri_when_is_null() { - UUri Uri = UriFactory.parseFromUri(null); + UUri Uri = UriSerializer.STRING.deserialize(null); assertTrue(Uri.isEmpty()); } @@ -50,7 +34,7 @@ public void test_parse_protocol_uri_when_is_null() { @DisplayName("Test parse uProtocol uri that is empty string") public void test_parse_protocol_uri_when_is_empty_string() { String uri = ""; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.isEmpty()); } @@ -58,7 +42,7 @@ public void test_parse_protocol_uri_when_is_empty_string() { @DisplayName("Test parse uProtocol uri with schema and slash") public void test_parse_protocol_uri_with_schema_and_slash() { String uri = "/"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -68,7 +52,7 @@ public void test_parse_protocol_uri_with_schema_and_slash() { @DisplayName("Test parse uProtocol uri with schema and double slash") public void test_parse_protocol_uri_with_schema_and_double_slash() { String uri = "//"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -78,7 +62,7 @@ public void test_parse_protocol_uri_with_schema_and_double_slash() { @DisplayName("Test parse uProtocol uri with schema and 3 slash and something") public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { String uri = "///body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -90,7 +74,7 @@ public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 4 slash and something") public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { String uri = "////body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().name().isBlank()); @@ -103,7 +87,7 @@ public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 5 slash and something") public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { String uri = "/////body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().isEmpty()); @@ -117,7 +101,7 @@ public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 6 slash and something") public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { String uri = "//////body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -127,7 +111,7 @@ public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { @DisplayName("Test parse uProtocol uri with local service no version") public void test_parse_protocol_uri_with_local_service_no_version() { String uri = "/body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -139,7 +123,7 @@ public void test_parse_protocol_uri_with_local_service_no_version() { @DisplayName("Test parse uProtocol uri with local service with version") public void test_parse_protocol_uri_with_local_service_with_version() { String uri = "/body.access/1"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -152,7 +136,7 @@ public void test_parse_protocol_uri_with_local_service_with_version() { @DisplayName("Test parse uProtocol uri with local service no version with resource name only") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_name_only() { String uri = "/body.access//door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -166,7 +150,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource name only") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_name_only() { String uri = "/body.access/1/door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -181,7 +165,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol uri with local service no version with resource and instance only") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance() { String uri = "/body.access//door.front_left"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -196,7 +180,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource and instance only") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_message() { String uri = "/body.access/1/door.front_left"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -212,7 +196,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol uri with local service no version with resource with instance and message") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance_and_message() { String uri = "/body.access//door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -228,7 +212,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource with instance and message") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_instance_and_message() { String uri = "/body.access/1/door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -245,7 +229,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol RPC uri with local service no version") public void test_parse_protocol_rpc_uri_with_local_service_no_version() { String uri = "/petapp//rpc.response"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); @@ -260,7 +244,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_no_version() { @DisplayName("Test parse uProtocol RPC uri with local service with version") public void test_parse_protocol_rpc_uri_with_local_service_with_version() { String uri = "/petapp/1/rpc.response"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); @@ -276,7 +260,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_with_version() { @DisplayName("Test parse uProtocol uri with remote service only device no domain") public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() { String uri = "//VCU"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -289,7 +273,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() @DisplayName("Test parse uProtocol uri with remote service only device and domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() { String uri = "//VCU.MY_CAR_VIN"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -303,7 +287,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() @DisplayName("Test parse uProtocol uri with remote service only device and cloud domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_domain() { String uri = "//cloud.uprotocol.example.com"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -317,7 +301,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_do @DisplayName("Test parse uProtocol uri with remote service no version") public void test_parse_protocol_uri_with_remote_service_no_version() { String uri = "//VCU.MY_CAR_VIN/body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -332,7 +316,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version() { @DisplayName("Test parse uProtocol uri with remote cloud service no version") public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { String uri = "//cloud.uprotocol.example.com/body.access"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -347,7 +331,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { @DisplayName("Test parse uProtocol uri with remote service with version") public void test_parse_protocol_uri_with_remote_service_with_version() { String uri = "//VCU.MY_CAR_VIN/body.access/1"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -363,7 +347,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version() { @DisplayName("Test parse uProtocol uri with remote cloud service with version") public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { String uri = "//cloud.uprotocol.example.com/body.access/1"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -379,7 +363,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { @DisplayName("Test parse uProtocol uri with remote service no version with resource name only") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access//door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -396,7 +380,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with remote cloud service no version with resource name only") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access//door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -413,7 +397,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re @DisplayName("Test parse uProtocol uri with remote service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -431,7 +415,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with remote cloud service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access/1/door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -449,7 +433,7 @@ public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_ @DisplayName("Test parse uProtocol uri with remote service no version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -467,7 +451,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with remote service with version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -486,7 +470,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with remote service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -505,7 +489,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with remote cloud service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access//door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -524,7 +508,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re @DisplayName("Test parse uProtocol uri with remote service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -544,7 +528,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with remote cloud service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access/1/door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -564,7 +548,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_ @DisplayName("Test parse uProtocol uri with remote service with version with resource with message when there is only device, no domain") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_with_message_device_no_domain() { String uri = "//VCU/body.access/1/door.front_left"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -582,7 +566,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol RPC uri with remote service no version") public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { String uri = "//bo.cloud/petapp//rpc.response"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("bo", Uri.uAuthority().device().get()); @@ -600,7 +584,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { @DisplayName("Test parse uProtocol RPC uri with remote service with version") public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { String uri = "//bo.cloud/petapp/1/rpc.response"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("bo", Uri.uAuthority().device().get()); @@ -618,7 +602,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { @Test @DisplayName("Test Create a uProtocol URI from null") public void test_build_protocol_uri_from__uri_when__uri_isnull() { - String uProtocolUri = UriFactory.buildUProtocolUri(null); + String uProtocolUri = UriSerializer.STRING.serialize(null); assertEquals("", uProtocolUri); } @@ -626,7 +610,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isnull() { @DisplayName("Test Create a uProtocol URI from an empty URI Object") public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { UUri Uri = UUri.empty(); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("", uProtocolUri); } @@ -635,7 +619,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { UEntity use = UEntity.empty(); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/", uProtocolUri); } @@ -644,7 +628,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access", uProtocolUri); } @@ -653,7 +637,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1", uProtocolUri); } @@ -662,7 +646,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access//door", uProtocolUri); } @@ -671,7 +655,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1/door", uProtocolUri); } @@ -680,7 +664,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access//door.front_left", uProtocolUri); } @@ -689,7 +673,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1/door.front_left", uProtocolUri); } @@ -698,7 +682,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access//door.front_left#Door", uProtocolUri); } @@ -707,7 +691,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_message() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1/door.front_left#Door", uProtocolUri); } @@ -716,7 +700,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access", uProtocolUri); } @@ -725,7 +709,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_device_with_domain_with_service_no_version() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//my_car_vin/body.access", uProtocolUri); } @@ -734,7 +718,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri); } @@ -743,7 +727,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.empty()); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri); } @@ -752,7 +736,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -761,7 +745,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door", uProtocolUri); } @@ -770,7 +754,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left", uProtocolUri); } @@ -779,7 +763,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1/door.front_left", uProtocolUri); } @@ -788,7 +772,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left", uProtocolUri); } @@ -797,7 +781,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { UEntity use = new UEntity("body.access", "1"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left#Door", uProtocolUri); } @@ -806,7 +790,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left#Door", uProtocolUri); } @@ -815,7 +799,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_local() { UAuthority uAuthority = UAuthority.local(); UEntity use = new UEntity("petapp", "1"); - String uProtocolUri = UriFactory.buildUriForRpc(uAuthority, use); + String uProtocolUri = UriSerializer.STRING.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("/petapp/1/rpc.response", uProtocolUri); } @@ -824,80 +808,10 @@ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_remote() { UAuthority uAuthority = UAuthority.remote("cloud", "uprotocol.example.com"); UEntity use = UEntity.fromName("petapp"); - String uProtocolUri = UriFactory.buildUriForRpc(uAuthority, use); + String uProtocolUri = UriSerializer.STRING.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("//cloud.uprotocol.example.com/petapp//rpc.response", uProtocolUri); } - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is local with software entity no version") - public void test_build_protocol_uri_for_service_accepting_rpc_local_uauthority_with_use_no_version() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.fromName("body.access"); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("/body.access//rpc.UpdateDoor", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is local with software entity with version") - public void test_build_protocol_uri_for_service_accepting_rpc_local_uauthority_with_use_with_version() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", "1"); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("/body.access/1/rpc.UpdateDoor", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is local, software entity is empty") - public void test_build_protocol_uri_for_service_accepting_rpc_local_uauthority_empty_use() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.fromName(" "); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("///rpc.UpdateDoor", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is remote with software entity no version") - public void test_build_protocol_uri_for_service_accepting_rpc_remote_uauthority_with_use_no_version() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = UEntity.fromName("body.access"); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("//vcu.my_vin/body.access//rpc.UpdateDoor", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is remote with software entity with version") - public void test_build_protocol_uri_for_service_accepting_rpc_remote_uauthority_with_use_with_version() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("//vcu.my_vin/body.access/1/rpc.UpdateDoor", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is remote cloud with software entity with version") - public void test_build_protocol_uri_for_service_accepting_rpc_remote_cloud_uauthority_with_use_with_version() { - UAuthority uAuthority = UAuthority.remote("cloud", "uprotocol.example.com"); - UEntity use = new UEntity("body.access", "1"); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("//cloud.uprotocol.example.com/body.access/1/rpc.UpdateDoor", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol URI for the service accepting the rpc, when authority is remote, software entity is empty") - public void test_build_protocol_uri_for_service_accepting_rpc_remote_uauthority_empty_use() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = UEntity.fromName(" "); - String methodName = "UpdateDoor"; - String uProtocolUri = UriFactory.buildMethodUri(uAuthority, use, methodName); - assertEquals("//vcu.my_vin///rpc.UpdateDoor", uProtocolUri); - } - @Test @DisplayName("Test Create a uProtocol URI from parts that are null") public void test_build_protocol_uri_from_parts_when_they_are_null() { @@ -905,7 +819,7 @@ public void test_build_protocol_uri_from_parts_when_they_are_null() { UEntity uSoftwareEntity = null; UResource uResource = null; UUri Uri = new UUri(uAuthority, uSoftwareEntity, uResource); - String uProtocolUri = UriFactory.buildUProtocolUri(Uri); + String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("", uProtocolUri); } @@ -915,7 +829,7 @@ public void test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authori UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); UEntity use = new UEntity("body.access", "1"); UResource uResource = UResource.fromName("door"); - String uProtocolUri = UriFactory.buildUProtocolUri(uAuthority, use, uResource); + String uProtocolUri = UriSerializer.STRING.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -925,7 +839,7 @@ public void test_custom_scheme_no_scheme_empty() { UAuthority uAuthority = null; UEntity uSoftwareEntity = null; UResource uResource = null; - String customUri = UriFactory.buildUProtocolUri(uAuthority, uSoftwareEntity, uResource); + String customUri = UriSerializer.STRING.serialize(new UUri(uAuthority, uSoftwareEntity, uResource)); assertTrue(customUri.isEmpty()); } @@ -935,7 +849,7 @@ public void test_custom_scheme_no_scheme() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); UEntity use = new UEntity("body.access", "1"); UResource uResource = UResource.fromName("door"); - String ucustomUri = UriFactory.buildUProtocolUri(uAuthority, use, uResource); + String ucustomUri = UriSerializer.STRING.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", ucustomUri); } @@ -943,7 +857,7 @@ public void test_custom_scheme_no_scheme() { @DisplayName("Test parse local uProtocol uri with custom scheme") public void test_parse_local_protocol_uri_with_custom_scheme() { String uri = "custom:/body.access//door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -960,7 +874,7 @@ public void test_parse_local_protocol_uri_with_custom_scheme() { public void test_parse_remote_protocol_uri_with_custom_scheme() { String uri = "custom://vcu.vin/body.access//door.front_left#Door"; String uri2 = "//vcu.vin/body.access//door.front_left#Door"; - UUri Uri = UriFactory.parseFromUri(uri); + UUri Uri = UriSerializer.STRING.deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -973,81 +887,7 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { assertEquals("front_left", Uri.uResource().instance().get()); assertTrue(Uri.uResource().message().isPresent()); assertEquals("Door", Uri.uResource().message().get()); - assertEquals(uri2, UriFactory.buildUProtocolUri(Uri)); - } - - @Test - @DisplayName("Test Create a uProtocol Short URI from a URI Object") - public void test_build_short_uri_from_uri() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("body.access", "1", (short)5); - UResource uResource = new UResource("door", "front_left", "Door", (short)3); - - UUri Uri = new UUri(uAuthority, use, uResource); - String uProtocolUri = UriFactory.buildUProtocolShortUri(Uri); - assertEquals("/5/1/3", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol Short URI for empty URI") - public void test_build_short_uri_from_uri_missing_ids() { - UUri Uri = UUri.empty(); - String uProtocolUri = UriFactory.buildUProtocolShortUri(Uri); - assertEquals("", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol Short URI for null URI") - public void test_build_short_uri_from_null_uri() { - String uProtocolUri = UriFactory.buildUProtocolShortUri(null); - assertEquals("", uProtocolUri); + assertEquals(uri2, UriSerializer.STRING.serialize(Uri)); } - - @Test - @DisplayName("Test Create a uProtocol Short URI with remote URI") - public void test_build_short_uri_from_remote_uri() { - String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; - InetAddress address = null; - try { - address = InetAddress.getByName(ipv6Address); - } - catch (UnknownHostException e) { - e.printStackTrace(); - } - UAuthority uAuthority = UAuthority.remote(address); - UEntity use = new UEntity("body.access", "1", (short)5); - UResource uResource = new UResource("door", "front_left", "Door", (short)3); - - String uProtocolUri = UriFactory.buildUProtocolShortUri(uAuthority, use, uResource); - assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/5/1/3", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol Short URI with remote URI without uEntity") - public void test_build_short_uri_from_remote_uri_missing_uentity() { - String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; - InetAddress address = null; - try { - address = InetAddress.getByName(ipv6Address); - } - catch (UnknownHostException e) { - e.printStackTrace(); - } - UAuthority uAuthority = UAuthority.remote(address); - - String uProtocolUri = UriFactory.buildUProtocolShortUri(uAuthority, UEntity.empty(), UResource.empty()); - assertEquals("//2001:db8:85a3:0:0:8a2e:370:7334/", uProtocolUri); - } - - @Test - @DisplayName("Test Create a uProtocol Short URI when address is missing") - public void test_build_short_uri_from_remote_uri_missing_address() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); - UEntity use = new UEntity("body.access", "1"); - UResource uResource = UResource.fromName("door"); - String ucustomUri = UriFactory.buildUProtocolShortUri(uAuthority, use, uResource); - assertEquals("///", ucustomUri); - } - -} \ No newline at end of file +} diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java deleted file mode 100644 index 48e2efbf..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.eclipse.uprotocol.uri.serializer; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -public class UriSerializerTest { - - @Test - @DisplayName("Test using the serializers") - public void test_using_the_serializers() { - final UUri uri = new UUri(UAuthority.local(), UEntity.fromName("hartley"), UResource.forRpc("raise")); - final String strUri = UriSerializer.STRING.serialize(uri); - assertEquals("/hartley//rpc.raise", strUri); - final UUri uri2 = UriSerializer.STRING.deserialize(strUri); - assertTrue(uri.equals(uri2)); - - - } - -} diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index 991fba69..79fc2ee6 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -27,13 +27,12 @@ import static org.junit.jupiter.api.Assertions.*; -import java.net.URI; - import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; + +import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; @@ -42,7 +41,7 @@ class UriValidatorTest { @Test @DisplayName("Test validate blank uri") public void test_validate_blank_uri() { - final UUri uri = UriFactory.parseFromUri(null); + final UUri uri = UriSerializer.STRING.deserialize(null); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -52,7 +51,7 @@ public void test_validate_blank_uri() { @Test @DisplayName("Test validate uri with no device name") public void test_validate_uri_with_no_entity_name() { - final UUri uri = UriFactory.parseFromUri("//"); + final UUri uri = UriSerializer.STRING.deserialize("//"); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -62,7 +61,7 @@ public void test_validate_uri_with_no_entity_name() { @Test @DisplayName("Test validate uri with uEntity") public void test_validate_uri_with_uEntity() { - final UUri uri = UriFactory.parseFromUri("/hartley"); + final UUri uri = UriSerializer.STRING.deserialize("/hartley"); final UStatus status = UriValidator.validate(uri); assertEquals(UStatus.ok(), status); } @@ -70,7 +69,7 @@ public void test_validate_uri_with_uEntity() { @Test @DisplayName("Test validate with malformed URI") public void test_validate_with_malformed_uri() { - final UUri uri = UriFactory.parseFromUri("hartley"); + final UUri uri = UriSerializer.STRING.deserialize("hartley"); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -91,7 +90,7 @@ public void test_validate_with_blank_uentity_name_uri() { @Test @DisplayName("Test validateRpcMethod with valid URI") public void test_validateRpcMethod_with_valid_uri() { - final UUri uri = UriFactory.parseFromUri("/hartley//rpc.echo"); + final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(UStatus.ok(), status); } @@ -99,7 +98,7 @@ public void test_validateRpcMethod_with_valid_uri() { @Test @DisplayName("Test validateRpcMethod with valid URI") public void test_validateRpcMethod_with_invalid_uri() { - final UUri uri = UriFactory.parseFromUri("/hartley/echo"); + final UUri uri = UriSerializer.STRING.deserialize("/hartley/echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.msg()); @@ -108,7 +107,7 @@ public void test_validateRpcMethod_with_invalid_uri() { @Test @DisplayName("Test validateRpcMethod with malformed URI") public void test_validateRpcMethod_with_malformed_uri() { - final UUri uri = UriFactory.parseFromUri("hartley"); + final UUri uri = UriSerializer.STRING.deserialize("hartley"); final UStatus status = UriValidator.validateRpcMethod(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -118,7 +117,7 @@ public void test_validateRpcMethod_with_malformed_uri() { @Test @DisplayName("Test validateRpcResponse with valid URI") public void test_validateRpcResponse_with_valid_uri() { - final UUri uri = UriFactory.parseFromUri("/hartley//rpc.response"); + final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.response"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(UStatus.ok(), status); } @@ -126,7 +125,7 @@ public void test_validateRpcResponse_with_valid_uri() { @Test @DisplayName("Test validateRpcResponse with malformed URI") public void test_validateRpcResponse_with_malformed_uri() { - final UUri uri = UriFactory.parseFromUri("hartley"); + final UUri uri = UriSerializer.STRING.deserialize("hartley"); final UStatus status = UriValidator.validateRpcResponse(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -136,7 +135,7 @@ public void test_validateRpcResponse_with_malformed_uri() { @Test @DisplayName("Test validateRpcResponse with rpc type") public void test_validateRpcResponse_with_rpc_type() { - final UUri uri = UriFactory.parseFromUri("/hartley//dummy.wrong"); + final UUri uri = UriSerializer.STRING.deserialize("/hartley//dummy.wrong"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); @@ -145,7 +144,7 @@ public void test_validateRpcResponse_with_rpc_type() { @Test @DisplayName("Test validateRpcResponse with invalid rpc response type") public void test_validateRpcResponse_with_invalid_rpc_response_type() { - final UUri uri = UriFactory.parseFromUri("/hartley//rpc.wrong"); + final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.wrong"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); @@ -154,38 +153,9 @@ public void test_validateRpcResponse_with_invalid_rpc_response_type() { @Test @DisplayName("Test validateLongUUri with valid URI") public void test_validateLongUUri_with_valid_uri() { - final UUri uri = UriFactory.parseFromUri("/hartley//rpc.echo"); - final UStatus status = UriValidator.validateLongUUri(UriFactory.buildUProtocolUri(uri)); - assertEquals(UStatus.ok(), status); - } - - @Test - @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI are identical") - public void test_validateEqualsShortMicroUri_with_valid_uri() { - final String shortUri = "/0/2/1"; - final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,2,0x0}; - final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); + final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.echo"); + final UStatus status = UriValidator.validateLongUUri(UriSerializer.STRING.serialize(uri)); assertEquals(UStatus.ok(), status); } - @Test - @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI are not identical") - public void test_validateEqualsShortMicroUri_with_invalid_uri() { - final String shortUri = "/0/1/1"; - final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x2,0x0}; - final UStatus status = UriValidator.validateEqualsShortMicroUri(shortUri, microUri); - assertEquals("Short URI Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='0', version='1', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} and Micro Uri Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, uEntity=UEntity{name='0', version='2', id='0'}, uResource=UResource{name='unknown', instance='null', message='null', id='1'}} are not equal.", status.msg()); - } - - @Test - @DisplayName("Test call validateEqualsShortMicroUri to test if a short and micro URI empty values") - public void test_validateEqualsShortMicroUri_with_missing_parameters() { - final String shortUri = "/0/1/1"; - final byte[] microUri = new byte[] {0x1,0x0,0x0,0x1,0x0,0x0,0x1,0x0}; - final UStatus status = UriValidator.validateEqualsShortMicroUri(null, microUri); - assertEquals("Short Uri is invalid.", status.msg()); - final UStatus status2 = UriValidator.validateEqualsShortMicroUri(shortUri, null); - assertEquals("Micro Uri is invalid.", status2.msg()); - } - } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index c68b6070..0728f280 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -25,7 +25,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.factory.UriFactory; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; @@ -763,7 +763,7 @@ public void test_validating_valid_id_attribute() { @Test @DisplayName("test validating invalid sink attribute") public void test_validating_invalid_sink_attribute() { - final UUri uri = UriFactory.parseFromUri("//"); + final UUri uri = UriSerializer.STRING.deserialize("//"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); @@ -778,7 +778,7 @@ public void test_validating_invalid_sink_attribute() { @Test @DisplayName("test validating valid sink attribute") public void test_validating_valid_sink_attribute() { - final UUri uri = UriFactory.parseFromUri("/haartley/1"); + final UUri uri = UriSerializer.STRING.deserialize("/haartley/1"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); @@ -894,7 +894,7 @@ public void test_validating_valid_commstatus_attribute() { @Test @DisplayName("test validating request message types") public void test_validating_request_message_types() { - final UUri sink = UriFactory.parseFromUri("/hartley/1/rpc.response"); + final UUri sink = UriSerializer.STRING.deserialize("/hartley/1/rpc.response"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) @@ -931,7 +931,7 @@ public void test_validating_request_validator_with_wrong_bad_ttl() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) - .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withSink(UriSerializer.STRING.deserialize("/hartley/1/rpc.response")) .withTtl(-1) .build(); @@ -949,7 +949,7 @@ public void test_validating_response_validator_with_wrong_bad_ttl() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) - .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withSink(UriSerializer.STRING.deserialize("/hartley/1/rpc.response")) .withTtl(-1) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); @@ -969,7 +969,7 @@ public void test_validating_response_validator_with_bad_reqid() { final UUID id = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) - .withSink(UriFactory.parseFromUri("/hartley/1/rpc.response")) + .withSink(UriSerializer.STRING.deserialize("/hartley/1/rpc.response")) .withTtl(100) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); From dda8f72d5e3583ea757f657d2098f207904ed16a Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 13 Sep 2023 21:58:06 -0400 Subject: [PATCH 30/52] Changed UEntity version from String to Integer --- .../uprotocol/uri/datamodel/UEntity.java | 16 +++--- .../uri/serializer/BytesUriSerializer.java | 6 +- .../uri/serializer/StringUriSerializer.java | 11 +++- .../factory/CloudEventFactoryTest.java | 18 +++--- .../validate/CloudEventValidatorTest.java | 4 +- .../uprotocol/uri/datamodel/UEntityTest.java | 26 ++++----- .../uprotocol/uri/datamodel/UUriTest.java | 10 ++-- .../serializer/BytesUriSerializerTest.java | 18 +++--- .../serializer/StringUriSerializerTest.java | 57 +++++++++---------- .../utransport/datamodel/UAttributeTest.java | 8 +-- .../validator/UAttributesValidatorTest.java | 40 ++++++------- 11 files changed, 110 insertions(+), 104 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 9c1fb70a..fd47258a 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -34,16 +34,16 @@ public class UEntity { private static final UEntity EMPTY = new UEntity("", null); - private final String name; - private final String version; - private final Short id; + private final String name; // uE Name + private final Integer version; // uE Major Version + private final Short id; // uE ID /** * Build an Software Entity that represents a communicating piece of software. * @param name The name of the software such as petpp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. */ - public UEntity(String name, String version, Short id) { + public UEntity(String name, Integer version, Short id) { Objects.requireNonNull(name, " Software Entity must have a name"); this.name = name; this.id = id; @@ -55,7 +55,7 @@ public UEntity(String name, String version, Short id) { * @param name The name of the software such as petpp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. */ - public UEntity(String name, String version) { + public UEntity(String name, Integer version) { Objects.requireNonNull(name, " Software Entity must have a name"); this.name = name; this.id = null; @@ -78,7 +78,7 @@ public static UEntity fromName(String name) { * @param id The software id. * @return Returns a UEntity with id but unknown name. */ - public static UEntity fromId(String version, Short id) { + public static UEntity fromId(Integer version, Short id) { Objects.requireNonNull(id, "ID must be supplied"); return new UEntity(String.valueOf(id), version, id); } @@ -112,8 +112,8 @@ public String name() { * @return Returns the software version if it exists. * If the version does not exist, the latest version of the service will be used. */ - public Optional version() { - return version == null || version.isBlank() ? Optional.empty() : Optional.of(version); + public Optional version() { + return Optional.ofNullable(version); } /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java index 8f0f5860..1be91792 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java @@ -124,8 +124,8 @@ public byte[] serialize(UUri Uri) { os.write(maybeUeId.get()); // UE_VERSION - String version = Uri.uEntity().version().orElse(""); - os.write(version.isEmpty() ? (byte)0 : Integer.parseInt(version.split("\\.")[0])); + Optional version = Uri.uEntity().version(); + os.write(!version.isPresent() ? (byte)0 : version.get().byteValue()); // UNUSED os.write((byte)0); @@ -191,7 +191,7 @@ else if (type.get() == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LEN int uiVersion = microUri[index++]; return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), - UEntity.fromId(String.valueOf(uiVersion), (short)ueId), + UEntity.fromId(uiVersion, (short)ueId), UResource.fromId((short)uResourceId)); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java index 63122308..2c633df6 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java @@ -183,7 +183,16 @@ public UUri deserialize(String uProtocolUri) { } - return new UUri(uAuthority, new UEntity(useName, useVersion.isBlank() ? null : useVersion), uResource); + Integer useVersionInt = null; + try { + if (!useVersion.isBlank()) { + useVersionInt = Integer.valueOf(useVersion); + } + } catch (NumberFormatException e) { + useVersionInt = null; + } + + return new UUri(uAuthority, new UEntity(useName, useVersionInt), uResource); } } diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index 2175e6b5..d0bd9da9 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -259,7 +259,7 @@ public void test_create_request_cloud_event_from_local_use() { String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri - UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); + UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); @@ -301,11 +301,11 @@ public void test_create_request_cloud_event_from_remote_use() { // Uri for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); - UEntity sourceUse = new UEntity("petapp", "1"); + UEntity sourceUse = new UEntity("petapp", 1); String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri - UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); + UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); @@ -347,11 +347,11 @@ public void test_create_request_cloud_event_from_remote_use() { public void test_create_response_cloud_event_originating_from_local_use() { // Uri for the application requesting the RPC - UEntity sourceUse = new UEntity("petapp", "1"); + UEntity sourceUse = new UEntity("petapp", 1); String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri - UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); + UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); @@ -398,7 +398,7 @@ public void test_create_response_cloud_event_originating_from_remote_use() { String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri - UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); + UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); @@ -441,11 +441,11 @@ public void test_create_response_cloud_event_originating_from_remote_use() { public void test_create_a_failed_response_cloud_event_originating_from_local_use() { // Uri for the application requesting the RPC - UEntity sourceUse = new UEntity("petapp", "1"); + UEntity sourceUse = new UEntity("petapp", 1); String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri - UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); + UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); @@ -493,7 +493,7 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri - UEntity methodSoftwareEntityService = new UEntity("body.access", "1"); + UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index 6260297b..baba8f85 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -622,7 +622,7 @@ void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() { @DisplayName("Test validate rpc topic uri with version, when it is valid") void test_rpc_topic__uri_with_version_when_it_is_valid() { - UEntity use = new UEntity("petapp", "1"); + UEntity use = new UEntity("petapp", 1); UAuthority uAuthority = UAuthority.remote("bo", "cloud"); UResource uResource = UResource.fromNameWithInstance("rpc", "response"); UUri Uri = new UUri(uAuthority, use, uResource); @@ -635,7 +635,7 @@ void test_rpc_topic__uri_with_version_when_it_is_valid() { @DisplayName("Test validate rpc topic uri with version, when it is not valid") void test_rpc_topic__uri_with_version_when_it_is_not_valid() { - UEntity use = new UEntity("petapp", "1"); + UEntity use = new UEntity("petapp", 1); UAuthority uAuthority = UAuthority.remote("bo", "cloud"); UResource uResource = UResource.fromNameWithInstance("body.access", "front_left"); UUri Uri = new UUri(uAuthority, use, uResource); diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 301271b6..4775690e 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -39,10 +39,10 @@ public void testHashCodeEquals() { @Test @DisplayName("Make sure the toString works") public void testToString() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); - assertEquals("1", use.version().get()); + assertEquals(1, use.version().get()); String expected = "UEntity{name='body.access', version='1', id='null'}"; assertEquals(expected, use.toString()); @@ -54,23 +54,23 @@ public void testToString() { @Test @DisplayName("Test creating a complete USE") public void test_create_use() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); - assertEquals("1", use.version().get()); + assertEquals(1, use.version().get()); } @Test @DisplayName("Test creating a complete USE with a null name, expect exception") public void test_create_use_null_name() { - Exception exception = assertThrows(NullPointerException.class, () -> new UEntity(null, "1")); + Exception exception = assertThrows(NullPointerException.class, () -> new UEntity(null, 1)); assertTrue(exception.getMessage().contains(" Software Entity must have a name")); } @Test @DisplayName("Test creating a USE with no version") public void test_create_use_with_no_version() { - UEntity use = new UEntity("body.access", " "); + UEntity use = new UEntity("body.access", null); assertEquals("body.access", use.name()); assertTrue(use.version().isEmpty()); @@ -104,7 +104,7 @@ public void test_is_empty() { UEntity use2 = new UEntity("", null); assertTrue(use2.isEmpty()); - UEntity use3 = new UEntity("", "1"); + UEntity use3 = new UEntity("", 1); assertFalse(use3.isEmpty()); UEntity use4 = new UEntity("petapp", null); @@ -114,10 +114,10 @@ public void test_is_empty() { @Test @DisplayName("Test creating UEntity with id") public void test_create_use_with_id() { - UEntity use = new UEntity("body.access", "1", (short)0); + UEntity use = new UEntity("body.access", 1, (short)0); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); - assertEquals("1", use.version().get()); + assertEquals(1, use.version().get()); assertTrue(use.id().isPresent()); assertEquals((int)0, (int)use.id().get()); assertEquals("UEntity{name='body.access', version='1', id='0'}", use.toString()); @@ -126,10 +126,10 @@ public void test_create_use_with_id() { @Test @DisplayName("Test creating UEntity with invalid id") public void test_create_use_with_invalid_id() { - UEntity use = new UEntity("body.access", "1", null); + UEntity use = new UEntity("body.access", 1, null); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); - assertEquals("1", use.version().get()); + assertEquals(1, use.version().get()); assertFalse(use.id().isPresent()); assertEquals("UEntity{name='body.access', version='1', id='null'}", use.toString()); } @@ -137,7 +137,7 @@ public void test_create_use_with_invalid_id() { @Test @DisplayName("Test isResolved and isLongForm() with valid resolved information") public void test_isResolved_with_valid_resolved_data() { - UEntity use = new UEntity("body.access", "1", (short)0); + UEntity use = new UEntity("body.access", 1, (short)0); assertTrue(use.isResolved()); assertTrue(use.isLongForm()); UEntity use3 = new UEntity("2", null, (short)1); @@ -148,7 +148,7 @@ public void test_isResolved_with_valid_resolved_data() { @Test @DisplayName("Test isResolved and isLongForm() with invalid resolved data") public void test_isResolved_with_invalid_resolved_data() { - UEntity use = new UEntity("body.access", "1", null); + UEntity use = new UEntity("body.access", 1, null); assertFalse(use.isResolved()); assertTrue(use.isLongForm()); UEntity use2 = UEntity.fromId(null, (short)1); diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 36923122..0239b183 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -46,7 +46,7 @@ public void testHashCodeEquals() { public void testToString() { UAuthority uAuthorityLocal = UAuthority.local(); UAuthority uAuthorityRemote = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromNameWithInstance("door", "front_left"); UUri uri = new UUri(uAuthorityLocal, use, uResource); @@ -87,7 +87,7 @@ public void test_create_full_local_uri() { @DisplayName("Test creating full remote uri") public void test_create_full_remote_uri() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = new UResource("door", "front_left", "Door"); UUri uri = new UUri(uAuthority, use, uResource); @@ -102,7 +102,7 @@ public void test_create_full_remote_uri() { @DisplayName("Test creating full uri with resource but no message using the constructor") public void test_create_uri_no_message_with_constructor() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); UUri uri = new UUri(uAuthority, use, "door"); @@ -115,7 +115,7 @@ public void test_create_uri_no_message_with_constructor() { @Test @DisplayName("Test creating a uri with a null authority, expect creation with an empty authority") public void test_create_uri_null_authority() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromNameWithInstance("door", "front_left"); UUri uri = new UUri(null, use, uResource); @@ -136,7 +136,7 @@ public void test_create_uri_null_use() { @DisplayName("Test creating a uri with a null ulitfi resource, expect creation with an empty resource") public void test_create_uri_null_uResource() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.empty(); UUri uri = new UUri(uAuthority, use, uResource); diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java index a554e886..1f3720b6 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java @@ -44,7 +44,7 @@ public void test_null() { @DisplayName("Test happy path Byte serialization of local UUri") public void test_serialize_uri() { UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.fromId("1", (short)2); + UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); @@ -59,19 +59,19 @@ public void test_serialize_uri() { @Test @DisplayName("Test serialize invalid UUris") public void test_serialize_invalid_uuris() throws UnknownHostException { - UUri uri = new UUri(UAuthority.local(), UEntity.fromId("", (short)1), UResource.empty()); + UUri uri = new UUri(UAuthority.local(), UEntity.fromId(null, (short)1), UResource.empty()); byte[] bytes = UriSerializer.BYTES.serialize(uri); assertEquals(bytes.length, 0); - UUri uri2 = new UUri(UAuthority.local(), new UEntity("", ""), UResource.forRpc("", (short)1)); + UUri uri2 = new UUri(UAuthority.local(), new UEntity("", null), UResource.forRpc("", (short)1)); byte[] bytes2 = UriSerializer.BYTES.serialize(uri2); assertEquals(bytes2.length, 0); - UUri uri3 = new UUri(UAuthority.remote("null", "null"), new UEntity("", ""), UResource.forRpc("", (short)1)); + UUri uri3 = new UUri(UAuthority.remote("null", "null"), new UEntity("", null), UResource.forRpc("", (short)1)); byte[] bytes3 = UriSerializer.BYTES.serialize(uri3); assertEquals(bytes3.length, 0); - UUri uri4 = new UUri(UAuthority.remote("vcu", "vin", null), new UEntity("", ""), UResource.forRpc("", (short)1)); + UUri uri4 = new UUri(UAuthority.remote("vcu", "vin", null), new UEntity("", null), UResource.forRpc("", (short)1)); byte[] bytes4 = UriSerializer.BYTES.serialize(uri4); assertEquals(bytes4.length, 0); } @@ -80,7 +80,7 @@ public void test_serialize_invalid_uuris() throws UnknownHostException { @DisplayName("Test serialize and deserialize IPv4 UUris") public void test_serialize_ipv4_uri() throws UnknownHostException { UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("192.168.1.100")); - UEntity use = UEntity.fromId("1", (short)2); + UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); @@ -93,7 +93,7 @@ public void test_serialize_ipv4_uri() throws UnknownHostException { @DisplayName("Test serialize and deserialize IPv6 UUris") public void test_serialize_ipv6_uri() throws UnknownHostException { UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UEntity use = UEntity.fromId("1", (short)2); + UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); @@ -106,7 +106,7 @@ public void test_serialize_ipv6_uri() throws UnknownHostException { @DisplayName("Test deserialize with missing information") public void test_deserialize_with_missing_information() throws UnknownHostException { UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UEntity use = UEntity.fromId("1", (short)2); + UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); byte[] bytes = UriSerializer.BYTES.serialize(uri); @@ -158,8 +158,6 @@ public void test_deserialize_with_missing_information() throws UnknownHostExcept byte[] byte9 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; UUri uri9 = UriSerializer.BYTES.deserialize(byte9); assertTrue(uri9.isEmpty()); - } - } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java index 31f6e232..b91205e3 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java @@ -78,8 +78,7 @@ public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().name().isBlank()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("body.access", Uri.uEntity().version().get()); + assertTrue(Uri.uEntity().version().isEmpty()); assertTrue(Uri.uResource().isEmpty()); } @@ -128,7 +127,7 @@ public void test_parse_protocol_uri_with_local_service_with_version() { assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertTrue(Uri.uResource().isEmpty()); } @@ -155,7 +154,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isEmpty()); assertTrue(Uri.uResource().message().isEmpty()); @@ -185,7 +184,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("front_left", Uri.uResource().instance().get()); @@ -217,7 +216,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("front_left", Uri.uResource().instance().get()); @@ -249,7 +248,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_with_version() { assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("rpc", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("response", Uri.uResource().instance().get()); @@ -339,7 +338,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version() { assertEquals("my_car_vin", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertTrue(Uri.uResource().isEmpty()); } @@ -355,7 +354,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertTrue(Uri.uResource().isEmpty()); } @@ -405,7 +404,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour assertEquals("my_car_vin", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isEmpty()); assertTrue(Uri.uResource().message().isEmpty()); @@ -423,7 +422,7 @@ public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_ assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isEmpty()); assertTrue(Uri.uResource().message().isEmpty()); @@ -459,7 +458,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour assertEquals("my_car_vin", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("front_left", Uri.uResource().instance().get()); @@ -516,7 +515,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour assertEquals("my_car_vin", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("front_left", Uri.uResource().instance().get()); @@ -536,7 +535,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_ assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("front_left", Uri.uResource().instance().get()); @@ -555,7 +554,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour assertTrue(Uri.uAuthority().domain().isEmpty()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("front_left", Uri.uResource().instance().get()); @@ -592,7 +591,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { assertEquals("cloud", Uri.uAuthority().domain().get()); assertEquals("petapp", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isPresent()); - assertEquals("1", Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().get()); assertEquals("rpc", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isPresent()); assertEquals("response", Uri.uResource().instance().get()); @@ -635,7 +634,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1", uProtocolUri); @@ -653,7 +652,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1/door", uProtocolUri); @@ -671,7 +670,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_message() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1/door.front_left", uProtocolUri); @@ -689,7 +688,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_message() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("/body.access/1/door.front_left#Door", uProtocolUri); @@ -716,7 +715,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_ @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri); @@ -725,7 +724,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a remote cloud authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.empty()); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri); @@ -734,7 +733,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); @@ -752,7 +751,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left", uProtocolUri); @@ -761,7 +760,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a remote cloud authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.fromNameWithInstance("door", "front_left")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1/door.front_left", uProtocolUri); @@ -779,7 +778,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); String uProtocolUri = UriSerializer.STRING.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left#Door", uProtocolUri); @@ -798,7 +797,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is local") public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_local() { UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("petapp", "1"); + UEntity use = new UEntity("petapp", 1); String uProtocolUri = UriSerializer.STRING.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("/petapp/1/rpc.response", uProtocolUri); } @@ -827,7 +826,7 @@ public void test_build_protocol_uri_from_parts_when_they_are_null() { @DisplayName("Test Create a uProtocol URI from the parts of URI Object with a remote authority with service and version with resource") public void test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authority_service_and_version_with_resource() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); String uProtocolUri = UriSerializer.STRING.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); @@ -847,7 +846,7 @@ public void test_custom_scheme_no_scheme_empty() { @DisplayName("Test Create a custom URI using no scheme") public void test_custom_scheme_no_scheme() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); - UEntity use = new UEntity("body.access", "1"); + UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); String ucustomUri = UriSerializer.STRING.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", ucustomUri); diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index 8ce3d088..abc3d9c8 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -165,7 +165,7 @@ public void test_create_uattributes_builder_for_basic_rpc_request_with_values() public void test_create_uattributes_builder_for_basic_rpc_response() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = UAttributes.forRpcResponse(id, sink, requestId) .withToken("someToken") @@ -186,7 +186,7 @@ public void test_create_uattributes_builder_for_basic_rpc_response_with_values() final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = UAttributes.forRpcResponse(id, UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), requestId) + new UEntity("petapp.ultifi.gm.com",1), requestId) .withToken("someToken") .withTtl(10000) .build(); @@ -365,7 +365,7 @@ public void test_is_uattributes_configured_for_rpc_response_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); final UUri sink = new UUri(UAuthority.remote("azure", "bo.ultifi.gm.com"), - new UEntity("petapp.ultifi.gm.com","1"), UResource.empty()); + new UEntity("petapp.ultifi.gm.com",1), UResource.empty()); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -380,7 +380,7 @@ public void test_scenarios_for_uattributes_not_configured_for_rpc_response_paylo final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); final UUri sink = new UUri(UAuthority.remote("azure", "bo.ultifi.gm.com"), - new UEntity("petapp.ultifi.gm.com","1"), UResource.empty()); + new UEntity("petapp.ultifi.gm.com",1), UResource.empty()); final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withReqId(requestId) diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index 0728f280..c13fa058 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -218,7 +218,7 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_reques @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request") public void test_validate_uAttributes_for_rpc_request_message_payload() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -235,7 +235,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload() { @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with all values") public void test_validate_uAttributes_for_rpc_request_message_payload_all_values() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -255,7 +255,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_all_values @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -272,7 +272,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid type") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_type() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -289,7 +289,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ty @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid priority") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_priority() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, null) .withSink(sink) @@ -306,7 +306,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_pr @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with missing time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_missing_ttl() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -322,7 +322,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_missing_tt @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ttl() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -368,7 +368,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_si @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid permission level") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_permission_level() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -386,7 +386,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_pe @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid communication status") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_communication_status() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -404,7 +404,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_co @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid request id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_request_id() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -424,7 +424,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_re @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response") public void test_validate_uAttributes_for_rpc_response_message_payload() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -441,7 +441,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload() { @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with all values") public void test_validate_uAttributes_for_rpc_response_message_payload_all_values() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -460,7 +460,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_all_value @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_id() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -477,7 +477,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_i @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid type") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_type() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -494,7 +494,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_t @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid priority") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_priority() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, null) .withSink(sink) @@ -511,7 +511,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_p @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid time to live") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_ttl() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -558,7 +558,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_s @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid permission level") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_permission_level() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -576,7 +576,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_p @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid communication status") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_communication_status() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -594,7 +594,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_c @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with missing request id") public void test_validate_uAttributes_for_rpc_response_message_payload_missing_request_id() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -610,7 +610,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_missing_r @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid request id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_request_id() { final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com","1"), UResource.fromNameWithInstance("rpc", "response")); + new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UUID reqid = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) From 8c02ab6c2b60f309cabdfe78023c1a556ea9d1b8 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 14 Sep 2023 07:59:39 -0400 Subject: [PATCH 31/52] cleanup, remove File event and add payload size --- .../cloudevent/datamodel/UCloudEventType.java | 1 - .../validate/CloudEventValidator.java | 32 ++++-------- .../uprotocol/uri/datamodel/UAuthority.java | 1 - .../eclipse/uprotocol/uri/datamodel/UUri.java | 1 - .../uri/serializer/StringUriSerializer.java | 1 - .../utransport/datamodel/UPayload.java | 28 ++++++++-- .../uuid/validate/UuidValidator.java | 19 ++++++- .../datamodel/UCloudEventTypeTest.java | 14 ----- .../factory/CloudEventFactoryTest.java | 5 -- .../validate/CloudEventValidatorTest.java | 51 ------------------- .../org/eclipse/uprotocol/rpc/RpcTest.java | 21 +------- .../uuid/validator/UuidValidatorTest.java | 1 + 12 files changed, 54 insertions(+), 121 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventType.java b/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventType.java index eaebd295..9ca06f43 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventType.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventType.java @@ -29,7 +29,6 @@ */ public enum UCloudEventType { PUBLISH ("pub.v1"), - FILE ("file.v1"), REQUEST ("req.v1"), RESPONSE ("res.v1"); diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java index e96b9203..f7e02732 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java @@ -54,15 +54,20 @@ public static CloudEventValidator getValidator(CloudEvent cloudEvent){ if (maybeType.isEmpty()) { return Validators.PUBLISH.validator(); } + + CloudEventValidator validator; switch (maybeType.get()){ - case FILE: - return Validators.FILE.validator(); case RESPONSE: - return Validators.RESPONSE.validator(); + validator = Validators.RESPONSE.validator(); + break; case REQUEST: - return Validators.REQUEST.validator(); + validator = Validators.REQUEST.validator(); + break; + default: + validator = Validators.PUBLISH.validator(); + break; } - return Validators.PUBLISH.validator(); + return validator; } /** @@ -71,7 +76,6 @@ public static CloudEventValidator getValidator(CloudEvent cloudEvent){ public enum Validators { PUBLISH (new Publish()), NOTIFICATION (new Notification()), - FILE (new File()), REQUEST (new Request()), RESPONSE (new Response()); @@ -296,22 +300,6 @@ public String toString() { } } - /** - * Implements Validations for a CloudEvent of type File. - */ - private static class File extends Publish { - - @Override - public ValidationResult validateType(CloudEvent cloudEvent) { - return "file.v1".equals(cloudEvent.getType()) ? ValidationResult.success() : - ValidationResult.failure(String.format("Invalid CloudEvent type [%s]. CloudEvent of type File must have a type of 'file.v1'", cloudEvent.getType())); - } - - @Override - public String toString() { - return "CloudEventValidator.File"; - } - } /** * Implements Validations for a CloudEvent for RPC Request. diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index a82ce94e..6f4960b8 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -22,7 +22,6 @@ package org.eclipse.uprotocol.uri.datamodel; import java.net.InetAddress; -import java.util.Arrays; import java.util.Objects; import java.util.Optional; import org.apache.commons.validator.routines.InetAddressValidator; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 4d7aadbf..74b113bd 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -21,7 +21,6 @@ package org.eclipse.uprotocol.uri.datamodel; -import java.net.InetAddress; import java.util.Objects; /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java index 2c633df6..3212a64b 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java @@ -25,7 +25,6 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import java.net.InetAddress; import java.util.Arrays; import java.util.Optional; import java.util.stream.Collectors; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java index 8a1681ad..fe7d0918 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java @@ -34,6 +34,8 @@ public class UPayload { private final byte[] data; + private final Integer size; // The size of the payload in bytes + private final USerializationHint hint; // Hint regarding the bytes contained within the UPayload @@ -42,11 +44,20 @@ public class UPayload { * @param data A byte array of the actual data. */ public UPayload(byte[] data, USerializationHint hint) { + this(data, data == null ? 0 : data.length, hint); + } + + /** + * Create a UPayload passing a fixed size + * @param data A byte array of the actual data. + */ + public UPayload(byte[] data, Integer size, USerializationHint hint) { this.hint = hint; this.data = data; - + this.size = size; } + /** * The actual serialized or raw data, which can be deserialized or simply used as is. * @return Returns the actual serialized or raw data, which can be deserialized or simply used as is. @@ -87,24 +98,33 @@ public boolean isEmpty() { return this.data == null || this.data.length == 0; } + /** + * The size of the payload in bytes + * @return Returns the size of the payload in bytes + */ + public Integer size() { + return size; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UPayload uPayload = (UPayload) o; - return Arrays.equals(data, uPayload.data) && this.hint == uPayload.hint; + return Arrays.equals(data, uPayload.data) && this.hint == uPayload.hint + && Objects.equals(this.size, uPayload.size); } @Override public int hashCode() { - return Objects.hash(Arrays.hashCode(data),hint); + return Objects.hash(Arrays.hashCode(data),hint, size); } @Override public String toString() { return "UPayload{" + - "data=" + Arrays.toString(data()) + " size=" + data().length + + "data=" + Arrays.toString(data()) + " size=" + size + ", hint=" + hint +'}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java b/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java index a5e2f975..a2f880ff 100644 --- a/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java @@ -38,15 +38,30 @@ public abstract class UuidValidator { public static UuidValidator getValidator(UUID uuid){ + UuidValidator validator; + switch (UUIDUtils.getVersion(uuid)){ case VERSION_TIME_ORDERED: - return UuidValidator.Validators.UUIDV6.validator(); + validator = UuidValidator.Validators.UUIDV6.validator(); + break; + case VERSION_UPROTOCOL: + validator = UuidValidator.Validators.UPROTOCOL.validator(); + break; + default: + validator = UuidValidator.Validators.INVALID.validator(); + break; } - return UuidValidator.Validators.UPROTOCOL.validator(); + return validator; } public enum Validators { + INVALID (new UuidValidator() { + @Override + public ValidationResult validateVersion(UUID uuid) { + return ValidationResult.failure("Invalid UUID Format"); + } + }), UUIDV6 (new UuidValidator.UUIDv6Validator()), UPROTOCOL (new UuidValidator.UUIDv8Validator()); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventTypeTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventTypeTest.java index 09bc6422..b8f257ef 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventTypeTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventTypeTest.java @@ -36,12 +36,6 @@ public void test_type_for_publish() { assertEquals("pub.v1", uCloudEventType.type()); } - @Test - @DisplayName("Test the type for a file event type") - public void test_type_for_file() { - UCloudEventType uCloudEventType = UCloudEventType.FILE; - assertEquals("file.v1", uCloudEventType.type()); - } @Test @DisplayName("Test the type for a request RPC event type") @@ -65,14 +59,6 @@ public void test_parse_publish_event_type_from_string() { assertEquals(UCloudEventType.PUBLISH, UCloudEventType.valueOfType(type).get()); } - @Test - @DisplayName("Test parsing the file event type from a string") - public void test_parse_file_event_type_from_string() { - String type = "file.v1"; - assertTrue(UCloudEventType.valueOfType(type).isPresent()); - assertEquals(UCloudEventType.FILE, UCloudEventType.valueOfType(type).get()); - } - @Test @DisplayName("Test parsing the request event type from a string") public void test_parse_request_event_type_from_string() { diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index d0bd9da9..d9f487d7 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -450,9 +450,6 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); - // fake payload - final Any protoPayload = buildProtoPayloadForTest(); - // additional attributes final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() .withHash("somehash") @@ -499,8 +496,6 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); - // fake payload - final Any protoPayload = buildProtoPayloadForTest(); // additional attributes final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index baba8f85..ca070406 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -94,29 +94,6 @@ void test_notification_cloud_event_type() { assertEquals("Invalid CloudEvent type [res.v1]. CloudEvent of type Publish must have a type of 'pub.v1'", status.getMessage()); } - @Test - @DisplayName("Test get a file cloud event validator") - void test_get_a_file_cloud_event_validator() { - CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() - .withType("file.v1"); - CloudEvent cloudEvent = builder.build(); - final CloudEventValidator validator = CloudEventValidator.getValidator(cloudEvent); - final Status status = validator.validateType(cloudEvent).toStatus(); - assertEquals(status, ValidationResult.STATUS_SUCCESS); - assertEquals("CloudEventValidator.File", validator.toString()); - } - - @Test - @DisplayName("Test file cloud event type") - void test_file_cloud_event_type() { - CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() - .withType("res.v1"); - CloudEvent cloudEvent = builder.build(); - final CloudEventValidator validator = CloudEventValidator.Validators.FILE.validator(); - final Status status = validator.validateType(cloudEvent).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid CloudEvent type [res.v1]. CloudEvent of type File must have a type of 'file.v1'", status.getMessage()); - } @Test @DisplayName("Test get a request cloud event validator") @@ -908,34 +885,6 @@ void test_notification_type_cloudevent_is_not_valid_invalid_sink() { assertEquals("Invalid Notification type CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.", status.getMessage()); } - @Test - @DisplayName("Test File type CloudEvent is valid everything is valid") - void test_file_type_cloudevent_is_valid_when_everything_is_valid() { - UUID uuid = UUIDFactory.Factories.UPROTOCOL.factory().create(); - CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() - .withId(uuid.toString()) - .withSource(URI.create("/body.access/1/door.front_left#Door")) - .withType(UCloudEventType.FILE.type()); - CloudEvent cloudEvent = builder.build(); - final CloudEventValidator validator = CloudEventValidator.Validators.FILE.validator(); - final Status status = validator.validate(cloudEvent); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test File type CloudEvent is not valid when source is empty") - void test_file_type_cloudevent_is_not_valid_when_source_is_empty() { - UUID uuid = UUIDFactory.Factories.UPROTOCOL.factory().create(); - CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() - .withId(uuid.toString()) - .withSource(URI.create("/")) - .withType(UCloudEventType.FILE.type()); - CloudEvent cloudEvent = builder.build(); - final CloudEventValidator validator = CloudEventValidator.Validators.FILE.validator(); - final Status status = validator.validate(cloudEvent); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid Publish type CloudEvent source [/]. Uri is missing uSoftware Entity name.", status.getMessage()); - } @Test @DisplayName("Test Request type CloudEvent is valid everything is valid") diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 1ae1b3bf..036ab841 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -240,18 +240,6 @@ void test_compose_with_failure_transform_Exception() { assertFalse(test.isCompletedExceptionally()); } - @Test - void test_compose_with_failure_2() { - CloudEvent request = buildCloudEventForTest().build(); -// final CompletableFuture> rpcResponse = -// mapResponseToRpcResponse(uLinkReturnsNumber3.invokeMethod(request), Int32Value.class) -// .thenApply(this::xxx) -// .thenApply(ur -> ); -// rpcResponse.thenAccept(RpcResult -> { -// assertTrue(RpcResult.isSuccess()); -// assertEquals(Int32Value.of(8), RpcResult.successValue()); -// }); - } @Test void test_success_invoke_method_happy_flow_using_mapResponseToRpcResponse() { @@ -470,7 +458,7 @@ void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto() { } @Test - void what_the_stub_looks_like() { + void what_the_stub_looks_like() throws InterruptedException { Rpc uLink = new Rpc() { @Override @@ -494,6 +482,7 @@ public String getResponseUri() { final CompletableFuture invokeMethodResponse = uLink.invokeMethod(request); CompletableFuture stubReturnValue = rpcResponse(invokeMethodResponse); + assertFalse(stubReturnValue.isCancelled()); } @@ -535,12 +524,6 @@ private static CompletableFuture rpcResponse return stubReturnValue; } - private Status crateErrorStatus(Exception e, Code exceptionCode) { - return Status.newBuilder() - .setCode(exceptionCode.getNumber()) - .setMessage(e.getMessage() == null ? "" : e.getMessage()) - .build(); - } private io.cloudevents.v1.proto.CloudEvent buildProtoPayloadForTest() { diff --git a/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java index dc8cab1f..81c35bb0 100644 --- a/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java @@ -66,6 +66,7 @@ void test_null_uuid() { final String str = UUIDUtils.toString(uuid); try { final UUID uuid2 = UUIDUtils.fromString(str); + assertEquals(uuid, uuid2); } catch(IllegalArgumentException e) { } From af5ee68e0d30fc139daa0a6429183ea44bf302ce Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 14 Sep 2023 14:53:33 -0400 Subject: [PATCH 32/52] RpcClient Implementation --- .../java/org/eclipse/uprotocol/rpc/Rpc.java | 47 -- .../org/eclipse/uprotocol/rpc/RpcClient.java | 17 +- .../org/eclipse/uprotocol/rpc/RpcMapper.java | 52 +- .../datamodel/USerializationHint.java | 17 +- .../eclipse/uprotocol/rpc/RpcMapperTest.java | 440 ---------------- .../org/eclipse/uprotocol/rpc/RpcTest.java | 483 ++++++++++-------- 6 files changed, 321 insertions(+), 735 deletions(-) delete mode 100644 src/main/java/org/eclipse/uprotocol/rpc/Rpc.java delete mode 100644 src/test/java/org/eclipse/uprotocol/rpc/RpcMapperTest.java diff --git a/src/main/java/org/eclipse/uprotocol/rpc/Rpc.java b/src/main/java/org/eclipse/uprotocol/rpc/Rpc.java deleted file mode 100644 index 0a371dc1..00000000 --- a/src/main/java/org/eclipse/uprotocol/rpc/Rpc.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.rpc; - -import com.google.protobuf.Any; -import io.cloudevents.CloudEvent; - -import java.util.concurrent.CompletableFuture; - -/** - * Interface for transport layers that want to implement RPC over for Layer 2. - */ -public interface Rpc { - - /** - * Support for RPC method invocation. - * @param requestEvent req.v1 CloudEvent. - * @return Returns the CompletableFuture with the result or exception. Tamara would rather have a CompletionStage since she likes it better - * when you program to an interface and not an implementation. - */ - CompletableFuture invokeMethod(CloudEvent requestEvent); - - /** - * This is the URI of the calling client, used for routing the response back to the caller. - * @return Returns the uri of the uE invoking the rpc. - */ - String getResponseUri(); -} diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java index 70db6bf5..0685ee7a 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java @@ -21,25 +21,24 @@ package org.eclipse.uprotocol.rpc; -import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UPayload; /** - * The RpcClient interface defines the RPC client API per the uProtocol specification - * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l2/README.adoc - * + * Interface used by code generators found in https://github.com/eclipse-uprotocol/uprotocol-core-api + * to invoke a method to support RPC. */ public interface RpcClient { /** * Support for RPC method invocation. - * @param topic The topic to invoke the method on. - * @param payload The payload to send. - * @param attributes The attributes to send. - * @return Returns the CompletableFuture with the result or exception. + * @param topic req.v1 CloudEvent. + * @param payload TODO + * @param attributes TODO + * @return Returns the CompletableFuture with the result or exception. */ - CompletionStage invokeMethod(UUri topic, UPayload payload, UAttributes attributes); + CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes); } diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java index 09460565..d90b4542 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java @@ -30,6 +30,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import org.eclipse.uprotocol.utransport.datamodel.UPayload; + /** * An interface that maps the returned value from uProtocol Layer 2 to the response in Layer3. */ @@ -42,7 +44,7 @@ public interface RpcMapper { * @return Returns a CompletableFuture containing the declared expected return type of the RPC method or an exception. * @param The declared expected return type of the RPC method. */ - static CompletableFuture mapResponse(CompletableFuture responseFuture, Class expectedClazz) { + static CompletableFuture mapResponse(CompletableFuture responseFuture, Class expectedClazz) { return responseFuture.handle((payload, exception) -> { // Unexpected exception if (exception != null) { @@ -51,12 +53,19 @@ static CompletableFuture mapResponse(CompletableFuture CompletableFuture mapResponse(CompletableFuture The declared expected return type of the RPC method. */ - static CompletableFuture> mapResponseToResult(CompletableFuture responseFuture, Class expectedClazz) { + static CompletableFuture> mapResponseToResult(CompletableFuture responseFuture, Class expectedClazz) { return responseFuture.handle((payload, exception) -> { // Unexpected exception if (exception != null) { throw new RuntimeException(exception.getMessage(), exception); } + if (payload == null) { throw new RuntimeException("Server returned a null payload. Expected " + expectedClazz.getName()); } - // Expected type - if (payload.is(expectedClazz)) { - if (Status.class.equals(expectedClazz)) { - return calculateStatusResult(payload); - } else { - return RpcResult.success(unpackPayload(payload, expectedClazz)); + Any any; + try { + any = Any.parseFrom(payload.data()); + + // Expected type + if (any.is(expectedClazz)) { + if (Status.class.equals(expectedClazz)) { + return calculateStatusResult(any); + } else { + return RpcResult.success(unpackPayload(any, expectedClazz)); + } } + // Status instead of the expected one + if (any.is(Status.class)) { + return calculateStatusResult(any); + } + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException(String.format("%s [%s]", e.getMessage(), Status.class.getName()), e); } - // Status instead of the expected one - if (payload.is(Status.class)) { - return calculateStatusResult(payload); - } + // Some other type instead of the expected one throw new RuntimeException(String.format("Unknown payload type [%s]. Expected [%s]", - payload.getTypeUrl(), expectedClazz.getName())); + any.getTypeUrl(), expectedClazz.getName())); }); } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java index f15efd13..c90b7a76 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java @@ -25,11 +25,20 @@ import java.util.Optional; public enum USerializationHint { + // Serialization hint is unknown UNKNOWN(0, ""), - PROTOBUF (1, "application/x-protobuf"), // data is a Base64 encoded protobuf string - JSON(2, "application/json"), // data is a UTF-8 string containing a JSON structure - SOMEIP(3, "application/x-someip"), // data is a UTF-8 string containing a JSON structure - RAW(4, "application/octet-stream"); // data is a Base64 encoded protobuf string of an Any object with the payload inside + + // serialized com.google.protobuf.Any type + PROTOBUF (1, "application/x-protobuf"), + + // data is a UTF-8 string containing a JSON structure + JSON(2, "application/json"), + + // data is a UTF-8 string containing a JSON structure + SOMEIP(3, "application/x-someip"), + + // Raw binary data that has not been serialized + RAW(4, "application/octet-stream"); private final int hintNumber; private final String mimeType; diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcMapperTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcMapperTest.java deleted file mode 100644 index 5fc8ffe2..00000000 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcMapperTest.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.rpc; - -import com.google.protobuf.Any; -import com.google.protobuf.Int32Value; -import com.google.rpc.Code; -import com.google.rpc.Status; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.net.URI; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import static org.junit.jupiter.api.Assertions.*; - -class RpcMapperTest { - - Rpc uLinkReturnsNumber3 = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Int32Value.of(3)); - return CompletableFuture.completedFuture(payload); - } - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkHappyPath = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(buildProtoPayloadForTest()); - return CompletableFuture.completedFuture(payload); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkWithStatusCodeInsteadOfHappyPath = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Status.newBuilder() - .setCode(Code.INVALID_ARGUMENT_VALUE) - .setMessage("boom") - .build()); - return CompletableFuture.completedFuture(payload); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkWithStatusCodeHappyPath = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Status.newBuilder() - .setCode(Code.OK_VALUE) - .setMessage("all good") - .build()); - return CompletableFuture.completedFuture(payload); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkWithStatusCodeThatFailedHappyPath = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Status.newBuilder() - .setCode(Code.INVALID_ARGUMENT_VALUE) - .setMessage("boom") - .build()); - return CompletableFuture.completedFuture(payload); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkWithNullInPayload = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - return CompletableFuture.completedFuture(null); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkThatCompletesWithAnException = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - return CompletableFuture.failedFuture(new RuntimeException("Boom")); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - Rpc uLinkThatReturnsTheWrongProto = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Int32Value.of(42)); - return CompletableFuture.completedFuture(payload); - } - - @Override - public String getResponseUri() { - return ""; - } - }; - - @Test - void test_compose_happy_path() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkReturnsNumber3.invokeMethod(request), Int32Value.class) - .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))) - .exceptionally(exception -> { - System.out.println("in exceptionally"); - return RpcResult.failure("boom", exception); - }); - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isSuccess()); - assertEquals(Int32Value.of(8), RpcResult.successValue()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - void test_compose_that_returns_status() throws ExecutionException, InterruptedException { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request), Int32Value.class) - .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))) - .exceptionally(exception -> { - System.out.println("in exceptionally"); - return RpcResult.failure("boom", exception); - }); - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isFailure()); - assertEquals(Code.INVALID_ARGUMENT_VALUE, RpcResult.failureValue().getCode()); - assertEquals("boom", RpcResult.failureValue().getMessage()); - }); - assertEquals(rpcResponse.get().failureValue().getCode(), Code.INVALID_ARGUMENT_VALUE); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - void test_compose_with_failure() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkThatCompletesWithAnException.invokeMethod(request), Int32Value.class) - .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))); - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Boom"); - } - - @Test - void test_compose_with_failure_transform_Exception() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkThatCompletesWithAnException.invokeMethod(request), Int32Value.class) - .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))) - .exceptionally(exception -> { - System.out.println("in exceptionally"); - return RpcResult.failure("boom", exception); - }); - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isFailure()); - assertEquals(Code.UNKNOWN_VALUE, RpcResult.failureValue().getCode()); - assertEquals("boom", RpcResult.failureValue().getMessage()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that returns the expected class successfully") - void test_success_invoke_method_happy_flow_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(cloudEvent -> assertEquals(buildProtoPayloadForTest(), cloudEvent)); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that returns successfully with null in the payload") - void test_success_invoke_method_that_has_null_payload_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkWithNullInPayload.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Server returned a null payload. Expected io.cloudevents.v1.proto.CloudEvent"); - - } - - @Test - @DisplayName("Invoke method that expects a Status payload and returns successfully with OK Status in the payload") - void test_success_invoke_method_happy_flow_that_returns_status_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkWithStatusCodeHappyPath.invokeMethod(request), Status.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(status -> { - assertEquals(Code.OK.getNumber(), status.getCode()); - assertEquals("all good", status.getMessage()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that expects a Status payload and returns successfully with a not OK Status in the payload") - void test_success_invoke_method_happy_flow_that_returns_failed_status_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkWithStatusCodeThatFailedHappyPath.invokeMethod(request), Status.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(status -> { - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("boom", status.getMessage()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that expects a CloudEvent payload and returns successfully with a Status in the payload") - void test_fail_invoke_method_when_invoke_method_returns_a_status_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Unknown payload type [type.googleapis.com/google.rpc.Status]. " + - "Expected [io.cloudevents.v1.proto.CloudEvent]"); - } - - @Test - @DisplayName("Invoke method that throws an exception") - void test_fail_invoke_method_when_invoke_method_threw_an_exception_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkThatCompletesWithAnException.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Boom"); - } - - @Test - @DisplayName("Invoke method that expects a CloudEvent in the payload but gets an Int32Value") - void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = - RpcMapper.mapResponse(uLinkThatReturnsTheWrongProto.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), - "java.lang.RuntimeException: Unknown payload type [type.googleapis.com/google.protobuf.Int32Value]. Expected [io.cloudevents.v1.proto.CloudEvent]"); - } - - @Test - @DisplayName("Invoke method that returns the expected class successfully, mapResponseToResult") - void test_success_invoke_method_happy_flow_using_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isSuccess()); - assertEquals(buildProtoPayloadForTest(), RpcResult.successValue()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that returns successfully with null in the payload, mapResponseToResult") - void test_success_invoke_method_that_has_null_payload_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkWithNullInPayload.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Server returned a null payload. Expected io.cloudevents.v1.proto.CloudEvent"); - - } - - @Test - @DisplayName("Invoke method that expects a Status payload and returns successfully with OK Status in the payload, mapResponseToResult") - void test_success_invoke_method_happy_flow_that_returns_status_using_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkWithStatusCodeHappyPath.invokeMethod(request), Status.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isSuccess()); - assertEquals(Code.OK.getNumber(), RpcResult.successValue().getCode()); - assertEquals("all good", RpcResult.successValue().getMessage()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that expects a Status payload and returns successfully with a not OK Status in the payload, mapResponseToResult") - void test_success_invoke_method_happy_flow_that_returns_failed_status_using_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkWithStatusCodeThatFailedHappyPath.invokeMethod(request), Status.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isFailure()); - assertEquals(Code.INVALID_ARGUMENT_VALUE, RpcResult.failureValue().getCode()); - assertEquals("boom", RpcResult.failureValue().getMessage()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that expects a CloudEvent payload and returns successfully with a Status in the payload, mapResponseToResult") - void test_fail_invoke_method_when_invoke_method_returns_a_status_using_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { - assertTrue(RpcResult.isFailure()); - assertEquals(Code.INVALID_ARGUMENT.getNumber(), RpcResult.failureValue().getCode()); - assertEquals("boom", RpcResult.failureValue().getMessage()); - }); - assertFalse(test.isCompletedExceptionally()); - } - - @Test - @DisplayName("Invoke method that throws an exception, mapResponseToResult") - void test_fail_invoke_method_when_invoke_method_threw_an_exception_using_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkThatCompletesWithAnException.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Boom"); - } - - @Test - @DisplayName("Invoke method that expects a CloudEvent in the payload but gets an Int32Value, mapResponseToResult") - void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_mapResponseToResultToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - RpcMapper.mapResponseToResult(uLinkThatReturnsTheWrongProto.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); - - assertTrue(rpcResponse.isCompletedExceptionally()); - Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), - "java.lang.RuntimeException: Unknown payload type [type.googleapis.com/google.protobuf.Int32Value]. Expected [io.cloudevents.v1.proto.CloudEvent]"); - } - - @Test - void test_unpack_payload_failed() { - Any payload = Any.pack(Int32Value.of(3)); - Exception exception = assertThrows(RuntimeException.class, () -> RpcMapper.unpackPayload(payload, Status.class)); - assertEquals(exception.getMessage(), - "Type of the Any message does not match the given class. [com.google.rpc.Status]"); - } - - private io.cloudevents.v1.proto.CloudEvent buildProtoPayloadForTest() { - return io.cloudevents.v1.proto.CloudEvent.newBuilder() - .setSpecVersion("1.0") - .setId("hello") - .setSource("http://example.com") - .setType("example.demo") - .setProtoData(Any.newBuilder().build()) - .putAttributes("ttl", io.cloudevents.v1.proto.CloudEvent.CloudEventAttributeValue.newBuilder() - .setCeString("3").build()) - .build(); - } - - private CloudEventBuilder buildCloudEventForTest() { - return CloudEventBuilder.v1() - .withId("hello") - .withType("req.v1") - .withSource(URI.create("//VCU.VIN/body.access")); - } - -} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 036ab841..54b22811 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -24,14 +24,19 @@ import com.google.protobuf.Any; import com.google.protobuf.Int32Value; import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; import com.google.rpc.Code; import com.google.rpc.Status; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; + +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; +import org.eclipse.uprotocol.utransport.datamodel.UAttributes; +import org.eclipse.uprotocol.utransport.datamodel.UPayload; +import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; +import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.net.URI; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -39,143 +44,90 @@ class RpcTest { - Rpc uLinkReturnsNumber3 = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Int32Value.of(3)); - return CompletableFuture.completedFuture(payload); - } + RpcClient ReturnsNumber3 = new RpcClient() { @Override - public String getResponseUri() { - return ""; + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + UPayload data = new UPayload(Any.pack(Int32Value.of(3)).toByteArray(), USerializationHint.PROTOBUF); + return CompletableFuture.completedFuture(data); } }; - Rpc uLinkHappyPath = new Rpc() { + RpcClient HappyPath = new RpcClient() { @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(buildProtoPayloadForTest()); - return CompletableFuture.completedFuture(payload); - } - - @Override - public String getResponseUri() { - return ""; + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + UPayload data = buildUPayload(); + return CompletableFuture.completedFuture(data); } }; - Rpc uLinkWithStatusCodeInsteadOfHappyPath = new Rpc() { + RpcClient WithStatusCodeInsteadOfHappyPath = new RpcClient() { @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Status.newBuilder() + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + Status status = Status.newBuilder() .setCode(Code.INVALID_ARGUMENT_VALUE) .setMessage("boom") - .build()); - return CompletableFuture.completedFuture(payload); - } + .build(); + Any any = Any.pack(status); + UPayload data = new UPayload(any.toByteArray(), USerializationHint.PROTOBUF); + + return CompletableFuture.completedFuture(data); + } + }; + RpcClient WithStatusCodeHappyPath = new RpcClient() { @Override - public String getResponseUri() { - return ""; - } + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + Status status = Status.newBuilder() + .setCode(Code.OK_VALUE) + .setMessage("all good") + .build(); + Any any = Any.pack(status); + UPayload data = new UPayload(any.toByteArray(), USerializationHint.PROTOBUF); + + return CompletableFuture.completedFuture(data); + } }; - Rpc uLinkThatCompletesWithAnException = new Rpc() { + RpcClient ThatBarfsCrapyPayload = new RpcClient() { @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - return CompletableFuture.failedFuture(new RuntimeException("Boom")); + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + UPayload response = new UPayload(new byte[] {0}, null, USerializationHint.RAW); + return CompletableFuture.completedFuture(response); } + }; + + RpcClient ThatCompletesWithAnException = new RpcClient() { @Override - public String getResponseUri() { - return ""; + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + return CompletableFuture.failedFuture(new RuntimeException("Boom")); } + }; - Rpc uLinkThatReturnsTheWrongProto = new Rpc() { + RpcClient ThatReturnsTheWrongProto = new RpcClient() { @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Int32Value.of(42)); - return CompletableFuture.completedFuture(payload); + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + Any any = Any.pack(Int32Value.of(42)); + return CompletableFuture.completedFuture(new UPayload(any.toByteArray(), USerializationHint.PROTOBUF)); } + }; + + + RpcClient WithNullInPayload = new RpcClient() { @Override - public String getResponseUri() { - return ""; + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + return CompletableFuture.completedFuture(null); } }; - private static CompletableFuture mapResponse(CompletableFuture responseFuture, - Class expectedClazz) { - return responseFuture.handle((payload, exception) -> { - // Unexpected exception - if (exception != null) { - throw new RuntimeException(exception.getMessage(), exception); - } - if (payload == null) { - throw new RuntimeException("Server returned a null payload. Expected " + expectedClazz.getName()); - } - // Expected type - if (payload.is(expectedClazz)) { - try { - return payload.unpack(expectedClazz); - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException(String.format("%s [%s]", e.getMessage(), expectedClazz.getName()), e); - } - } - // Status instead of the expected one - if (payload.is(Status.class)) { - try { - Status status = payload.unpack(Status.class); - throw new RuntimeException(String.format("Error returned, status code: [%s], message: [%s]", - Code.forNumber(status.getCode()), status.getMessage())); - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException(String.format("%s [%s]", e.getMessage(), Status.class.getName()), e); - } - } - // Some other type instead of the expected one - throw new RuntimeException(String.format("Unknown payload type [%s]. Expected [%s]", - payload.getTypeUrl(), expectedClazz.getName())); - }); - } - - private static CompletableFuture> mapResponseToRpcResponse(CompletableFuture responseFuture, - Class expectedClazz) { - return responseFuture.handle((payload, exception) -> { - // Unexpected exception - if (exception != null) { - throw new RuntimeException(exception.getMessage(), exception); - } - if (payload == null) { - throw new RuntimeException("Server returned a null payload. Expected " + expectedClazz.getName()); - } - // Expected type - if (payload.is(expectedClazz)) { - try { - return RpcResult.success(payload.unpack(expectedClazz)); - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException(String.format("%s [%s]", e.getMessage(), expectedClazz.getName()), e); - } - } - // Status instead of the expected one - if (payload.is(Status.class)) { - try { - return RpcResult.failure(payload.unpack(Status.class)); - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException(String.format("%s [%s]", e.getMessage(), Status.class.getName()), e); - } - } - // Some other type instead of the expected one - throw new RuntimeException(String.format("Unknown payload type [%s]. Expected [%s]", - payload.getTypeUrl(), expectedClazz.getName())); - }); - } @Test void test_compose_happy_path() { - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkReturnsNumber3.invokeMethod(request), Int32Value.class) + UPayload payload = buildUPayload(); + final CompletableFuture> rpcResponse = + RpcMapper.mapResponseToResult(ReturnsNumber3.invokeMethod(buildTopic(), payload, buildUAttributes()), Int32Value.class) .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))) .exceptionally(exception -> { System.out.println("in exceptionally"); @@ -191,9 +143,9 @@ void test_compose_happy_path() { @Test void test_compose_that_returns_status() throws ExecutionException, InterruptedException { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request), Int32Value.class) + RpcMapper.mapResponseToResult(WithStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), Int32Value.class) .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))) .exceptionally(exception -> { System.out.println("in exceptionally"); @@ -212,9 +164,9 @@ void test_compose_that_returns_status() throws ExecutionException, InterruptedEx @Test void test_compose_with_failure() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkThatCompletesWithAnException.invokeMethod(request), Int32Value.class) + RpcMapper.mapResponseToResult(ThatCompletesWithAnException.invokeMethod(buildTopic(), payload, buildUAttributes()), Int32Value.class) .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))); assertTrue(rpcResponse.isCompletedExceptionally()); Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); @@ -223,9 +175,9 @@ void test_compose_with_failure() { @Test void test_compose_with_failure_transform_Exception() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkThatCompletesWithAnException.invokeMethod(request), Int32Value.class) + RpcMapper.mapResponseToResult(ThatCompletesWithAnException.invokeMethod(buildTopic(), payload, buildUAttributes()), Int32Value.class) .thenApply(ur -> ur.map(i -> Int32Value.of(i.getValue()+5))) .exceptionally(exception -> { System.out.println("in exceptionally"); @@ -243,23 +195,24 @@ void test_compose_with_failure_transform_Exception() { @Test void test_success_invoke_method_happy_flow_using_mapResponseToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); + final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponseToResult(HappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertFalse(rpcResponse.isCompletedExceptionally()); final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { assertTrue(RpcResult.isSuccess()); - assertEquals(buildProtoPayloadForTest(), RpcResult.successValue()); + assertEquals(buildCloudEvent(), RpcResult.successValue()); }); assertFalse(test.isCompletedExceptionally()); } @Test void test_fail_invoke_method_when_invoke_method_returns_a_status_using_mapResponseToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponseToResult(WithStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertFalse(rpcResponse.isCompletedExceptionally()); final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { @@ -272,9 +225,9 @@ void test_fail_invoke_method_when_invoke_method_returns_a_status_using_mapRespon @Test void test_fail_invoke_method_when_invoke_method_threw_an_exception_using_mapResponseToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkThatCompletesWithAnException.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponseToResult(ThatCompletesWithAnException.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertTrue(rpcResponse.isCompletedExceptionally()); Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); @@ -283,9 +236,9 @@ void test_fail_invoke_method_when_invoke_method_threw_an_exception_using_mapResp @Test void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_mapResponseToRpcResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture> rpcResponse = - mapResponseToRpcResponse(uLinkThatReturnsTheWrongProto.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponseToResult(ThatReturnsTheWrongProto.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertTrue(rpcResponse.isCompletedExceptionally()); Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); @@ -293,36 +246,35 @@ void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_mapRes "java.lang.RuntimeException: Unknown payload type [type.googleapis.com/google.protobuf.Int32Value]. Expected [io.cloudevents.v1.proto.CloudEvent]"); } - // --- @Test void test_success_invoke_method_happy_flow_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture rpcResponse = - mapResponse(uLinkHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponse(HappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertFalse(rpcResponse.isCompletedExceptionally()); - final CompletableFuture test = rpcResponse.thenAccept(cloudEvent -> assertEquals(buildProtoPayloadForTest(), cloudEvent)); + final CompletableFuture test = rpcResponse.thenAccept(cloudEvent -> assertEquals(buildCloudEvent(), cloudEvent)); assertFalse(test.isCompletedExceptionally()); } @Test void test_fail_invoke_method_when_invoke_method_returns_a_status_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture rpcResponse = - mapResponse(uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponse(WithStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertTrue(rpcResponse.isCompletedExceptionally()); Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); - assertEquals(exception.getMessage(), "java.lang.RuntimeException: Error returned, status code: [INVALID_ARGUMENT], message: [boom]"); + assertEquals(exception.getMessage(), "java.lang.RuntimeException: Unknown payload type [type.googleapis.com/google.rpc.Status]. Expected [io.cloudevents.v1.proto.CloudEvent]"); } @Test void test_fail_invoke_method_when_invoke_method_threw_an_exception_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture rpcResponse = - mapResponse(uLinkThatCompletesWithAnException.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponse(ThatCompletesWithAnException.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertTrue(rpcResponse.isCompletedExceptionally()); Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); @@ -331,9 +283,9 @@ void test_fail_invoke_method_when_invoke_method_threw_an_exception_using_mapResp @Test void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_mapResponse() { - CloudEvent request = buildCloudEventForTest().build(); + UPayload payload = buildUPayload(); final CompletableFuture rpcResponse = - mapResponse(uLinkThatReturnsTheWrongProto.invokeMethod(request), io.cloudevents.v1.proto.CloudEvent.class); + RpcMapper.mapResponse(ThatReturnsTheWrongProto.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); assertTrue(rpcResponse.isCompletedExceptionally()); Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); @@ -341,60 +293,65 @@ void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_mapRes "java.lang.RuntimeException: Unknown payload type [type.googleapis.com/google.protobuf.Int32Value]. Expected [io.cloudevents.v1.proto.CloudEvent]"); } - // --- - + @Test void test_success_invoke_method_happy_flow() { //Stub code - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = uLinkHappyPath.invokeMethod(request); + UPayload data = buildUPayload(); + final CompletableFuture rpcResponse = HappyPath.invokeMethod(buildTopic(), data, buildUAttributes()); final CompletableFuture stubReturnValue = rpcResponse.handle((payload, exception) -> { - // happy flow, no exception - assertNull(exception); + Any any; + assertTrue(true); + assertFalse(true); + + try { + any = Any.parseFrom(payload.data()); + // happy flow, no exception + assertNull(exception); - // check the payload is not google.rpc.Status - assertFalse(payload.is(Status.class)); + // check the payload is not google.rpc.Status + assertFalse(any.is(Status.class)); - // check the payload is the cloud event we build - assertTrue(payload.is(io.cloudevents.v1.proto.CloudEvent.class)); + // check the payload is the cloud event we build + assertTrue(any.is(io.cloudevents.v1.proto.CloudEvent.class)); - try { - return payload.unpack(io.cloudevents.v1.proto.CloudEvent.class); + return any.unpack(io.cloudevents.v1.proto.CloudEvent.class); } catch (InvalidProtocolBufferException e) { throw new RuntimeException(e); } }); - stubReturnValue.thenAccept(cloudEvent -> assertEquals(buildProtoPayloadForTest(), cloudEvent)); + stubReturnValue.thenAccept(cloudEvent -> assertEquals(buildUPayload(), cloudEvent)); } @Test void test_fail_invoke_method_when_invoke_method_returns_a_status() { //Stub code - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = uLinkWithStatusCodeInsteadOfHappyPath.invokeMethod(request); + UPayload data = buildUPayload(); + final CompletableFuture rpcResponse = WithStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), data, buildUAttributes()); final CompletableFuture stubReturnValue = rpcResponse.handle((payload, exception) -> { - // happy flow, no exception - assertNull(exception); + try { + Any any = Any.parseFrom(payload.data()); + // happy flow, no exception + assertNull(exception); - // check the payload not google.rpc.Status - assertTrue(payload.is(Status.class)); + // check the payload not google.rpc.Status + assertTrue(any.is(Status.class)); - // check the payload is not the type we expected - assertFalse(payload.is(io.cloudevents.v1.proto.CloudEvent.class)); + // check the payload is not the type we expected + assertFalse(any.is(io.cloudevents.v1.proto.CloudEvent.class)); - // we know it is a Status - so let's unpack it - try { - Status status = payload.unpack(Status.class); + // we know it is a Status - so let's unpack it + + Status status = any.unpack(Status.class); throw new RuntimeException(String.format("Error returned, status code: [%s], message: [%s]", Code.forNumber(status.getCode()), status.getMessage())); } catch (InvalidProtocolBufferException e) { throw new RuntimeException(e); } - }); assertTrue(stubReturnValue.isCompletedExceptionally()); @@ -407,8 +364,8 @@ void test_fail_invoke_method_when_invoke_method_returns_a_status() { @Test void test_fail_invoke_method_when_invoke_method_threw_an_exception() { //Stub code - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = uLinkThatCompletesWithAnException.invokeMethod(request); + UPayload data = buildUPayload(); + final CompletableFuture rpcResponse = ThatCompletesWithAnException.invokeMethod(buildTopic(), data, buildUAttributes()); final CompletableFuture stubReturnValue = rpcResponse.handle((payload, exception) -> { // exception was thrown @@ -430,21 +387,22 @@ void test_fail_invoke_method_when_invoke_method_threw_an_exception() { @Test void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto() { //Stub code - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture rpcResponse = uLinkThatReturnsTheWrongProto.invokeMethod(request); + UPayload data = buildUPayload(); + final CompletableFuture rpcResponse = ThatReturnsTheWrongProto.invokeMethod(buildTopic(), data, buildUAttributes()); final CompletableFuture stubReturnValue = rpcResponse.handle((payload, exception) -> { - // happy flow, no exception - assertNull(exception); + try { + Any any = Any.parseFrom(payload.data()); + // happy flow, no exception + assertNull(exception); - // check the payload is not google.rpc.Status - assertFalse(payload.is(Status.class)); + // check the payload is not google.rpc.Status + assertFalse(any.is(Status.class)); - // check the payload is the cloud event we build - assertFalse(payload.is(io.cloudevents.v1.proto.CloudEvent.class)); + // check the payload is the cloud event we build + assertFalse(any.is(io.cloudevents.v1.proto.CloudEvent.class)); - try { - return payload.unpack(io.cloudevents.v1.proto.CloudEvent.class); + return any.unpack(io.cloudevents.v1.proto.CloudEvent.class); } catch (InvalidProtocolBufferException e) { throw new RuntimeException(String.format("%s [%s]", e.getMessage(), "io.cloudevents.v1.proto.CloudEvent.class"), e); } @@ -458,58 +416,169 @@ void test_fail_invoke_method_when_invoke_method_returns_a_bad_proto() { } @Test - void what_the_stub_looks_like() throws InterruptedException { + @DisplayName("Invoke method that returns successfully with null in the payload") + void test_success_invoke_method_that_has_null_payload_mapResponse() { + UPayload payload = buildUPayload(); + final CompletableFuture rpcResponse = + RpcMapper.mapResponse(WithNullInPayload.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); - Rpc uLink = new Rpc() { - @Override - public CompletableFuture invokeMethod(CloudEvent requestEvent) { - Any payload = Any.pack(Status.newBuilder() - .setCode(Code.INVALID_ARGUMENT_VALUE) - .setMessage("boom") - .build()); - return CompletableFuture.completedFuture(payload); - } + assertTrue(rpcResponse.isCompletedExceptionally()); + Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); + assertEquals(exception.getMessage(), "java.lang.RuntimeException: Server returned a null payload. Expected io.cloudevents.v1.proto.CloudEvent"); + + } + + + @Test + @DisplayName("Invoke method that returns successfully with null in the payload, mapResponseToResult") + void test_success_invoke_method_that_has_null_payload_mapResponseToResultToRpcResponse() { + UPayload payload = buildUPayload(); + final CompletableFuture> rpcResponse = + RpcMapper.mapResponseToResult(WithNullInPayload.invokeMethod(buildTopic(), payload, buildUAttributes()), io.cloudevents.v1.proto.CloudEvent.class); + + assertTrue(rpcResponse.isCompletedExceptionally()); + Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); + assertEquals(exception.getMessage(), "java.lang.RuntimeException: Server returned a null payload. Expected io.cloudevents.v1.proto.CloudEvent"); + + } + + + @Test + @DisplayName("Invoke method that expects a Status payload and returns successfully with OK Status in the payload") + void test_success_invoke_method_happy_flow_that_returns_status_using_mapResponse() { + UPayload payload = buildUPayload(); + final CompletableFuture rpcResponse = + RpcMapper.mapResponse(WithStatusCodeHappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), Status.class); + + assertFalse(rpcResponse.isCompletedExceptionally()); + final CompletableFuture test = rpcResponse.thenAccept(status -> { + assertEquals(Code.OK.getNumber(), status.getCode()); + assertEquals("all good", status.getMessage()); + }); + assertFalse(test.isCompletedExceptionally()); + } + + @Test + @DisplayName("Invoke method that expects a Status payload and returns successfully with OK Status in the payload, mapResponseToResult") + void test_success_invoke_method_happy_flow_that_returns_status_using_mapResponseToResultToRpcResponse() { + UPayload payload = buildUPayload(); + final CompletableFuture> rpcResponse = + RpcMapper.mapResponseToResult(WithStatusCodeHappyPath.invokeMethod(buildTopic(), payload, buildUAttributes()), Status.class); + + assertFalse(rpcResponse.isCompletedExceptionally()); + final CompletableFuture test = rpcResponse.thenAccept(RpcResult -> { + assertTrue(RpcResult.isSuccess()); + assertEquals(Code.OK.getNumber(), RpcResult.successValue().getCode()); + assertEquals("all good", RpcResult.successValue().getMessage()); + }); + assertFalse(test.isCompletedExceptionally()); + } + + @Test + void test_unpack_payload_failed() { + Any payload = Any.pack(Int32Value.of(3)); + Exception exception = assertThrows(RuntimeException.class, () -> RpcMapper.unpackPayload(payload, Status.class)); + assertEquals(exception.getMessage(), + "Type of the Any message does not match the given class. [com.google.rpc.Status]"); + } + + @Test + @DisplayName("test invalid payload that is not of type any") + void test_invalid_payload_that_is_not_type_any() { + UPayload payload = buildUPayload(); + final CompletableFuture rpcResponse = + RpcMapper.mapResponse(ThatBarfsCrapyPayload.invokeMethod(buildTopic(), payload, buildUAttributes()), Status.class); + + assertTrue(rpcResponse.isCompletedExceptionally()); + Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); + assertEquals(exception.getMessage(), + "java.lang.RuntimeException: Protocol message contained an invalid tag (zero). [com.google.rpc.Status]");; + } + @Test + @DisplayName("test invalid payload that is not of type any") + void test_invalid_payload_that_is_not_type_any_map_to_result() { + UPayload payload = buildUPayload(); + final CompletableFuture> rpcResponse = + RpcMapper.mapResponseToResult(ThatBarfsCrapyPayload.invokeMethod(buildTopic(), payload, buildUAttributes()), Status.class); + + assertTrue(rpcResponse.isCompletedExceptionally()); + Exception exception = assertThrows(java.util.concurrent.ExecutionException.class, rpcResponse::get); + assertEquals(exception.getMessage(), + "java.lang.RuntimeException: Protocol message contained an invalid tag (zero). [com.google.rpc.Status]");; + } + + @Test + void what_the_stub_looks_like() throws InterruptedException { + + RpcClient client = new RpcClient() { @Override - public String getResponseUri() { - return ""; + public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { + UPayload data = new UPayload(null, null, null); + return CompletableFuture.completedFuture(data); } }; //Stub code - CloudEvent request = buildCloudEventForTest().build(); - final CompletableFuture invokeMethodResponse = uLink.invokeMethod(request); + UPayload payload = buildUPayload(); + final CompletableFuture invokeMethodResponse = client.invokeMethod(buildTopic(), payload, buildUAttributes()); CompletableFuture stubReturnValue = rpcResponse(invokeMethodResponse); assertFalse(stubReturnValue.isCancelled()); } - private static CompletableFuture rpcResponse(CompletableFuture invokeMethodResponse) { + private static io.cloudevents.v1.proto.CloudEvent buildCloudEvent() { + return io.cloudevents.v1.proto.CloudEvent.newBuilder() + .setSpecVersion("1.0") + .setId("HARTLEY IS THE BEST") + .setSource("http://example.com") + .build(); + } + private static UPayload buildUPayload() { + Any any = Any.pack(buildCloudEvent()); + return new UPayload(any.toByteArray(), USerializationHint.PROTOBUF); + } + + private static UUri buildTopic() { + return UriSerializer.STRING.deserialize("//vcu.vin/hartley/1/rpc.Raise"); + } + + private static UAttributes buildUAttributes() { + return UAttributes.forRpcRequest( + UUIDFactory.Factories.UPROTOCOL.factory().create(), + UUri.rpcResponse(null, UEntity.fromName("hartley"))).build(); + } + + private static CompletableFuture rpcResponse(CompletableFuture invokeMethodResponse) { final CompletableFuture stubReturnValue = invokeMethodResponse.handle((payload, exception) -> { + Any any; + try { + any = Any.parseFrom(payload.data()); + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException(e.getMessage(), e); + } + // invoke method had some unexpected problem. if (exception != null) { throw new RuntimeException(exception.getMessage(), exception); } - if (payload == null) { - throw new RuntimeException("Server returned a null payload. Expected a io.cloudevents.v1.proto.CloudEvent"); - } - + // test to see if we have expected type - if (payload.is(io.cloudevents.v1.proto.CloudEvent.class)) { + if (any.is(io.cloudevents.v1.proto.CloudEvent.class)) { try { - return payload.unpack(io.cloudevents.v1.proto.CloudEvent.class); + return any.unpack(io.cloudevents.v1.proto.CloudEvent.class); } catch (InvalidProtocolBufferException e) { throw new RuntimeException(e.getMessage(), e); } } // this will be called only if expected return type is not status, but status was returned to indicate a problem. - if (payload.is(Status.class)) { + if (any.is(Status.class)) { try { - Status status = payload.unpack(Status.class); + Status status = any.unpack(Status.class); throw new RuntimeException(String.format("Error returned, status code: [%s], message: [%s]", Code.forNumber(status.getCode()), status.getMessage())); } catch (InvalidProtocolBufferException e) { @@ -517,33 +586,11 @@ private static CompletableFuture rpcResponse } } - throw new RuntimeException(String.format("Unknown payload type [%s]", payload.getTypeUrl())); + throw new RuntimeException(String.format("Unknown payload type [%s]", any.getTypeUrl())); }); return stubReturnValue; } - - - private io.cloudevents.v1.proto.CloudEvent buildProtoPayloadForTest() { - io.cloudevents.v1.proto.CloudEvent cloudEventProto = io.cloudevents.v1.proto.CloudEvent.newBuilder() - .setSpecVersion("1.0") - .setId("hello") - .setSource("http://example.com") - .setType("example.demo") - .setProtoData(Any.newBuilder().build()) - .putAttributes("ttl", io.cloudevents.v1.proto.CloudEvent.CloudEventAttributeValue.newBuilder() - .setCeString("3").build()) - .build(); - return cloudEventProto; - } - - private CloudEventBuilder buildCloudEventForTest() { - return CloudEventBuilder.v1() - .withId("hello") - .withType("req.v1") - .withSource(URI.create("//VCU.VIN/body.access")); - } - } \ No newline at end of file From 093c5bdf092eafb31cfe0c6e9c488d0235f61ab5 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Fri, 15 Sep 2023 12:54:46 -0400 Subject: [PATCH 33/52] Fixed documentation & rename serializer In lieu of having to constantly refer to STRING is long and byte[] is micro, I'm just using the same nomenclature everywhere. --- .../validate/CloudEventValidator.java | 8 +- .../org/eclipse/uprotocol/rpc/RpcClient.java | 13 +- .../org/eclipse/uprotocol/rpc/RpcMapper.java | 8 +- .../uprotocol/uri/datamodel/UAuthority.java | 8 +- .../uprotocol/uri/datamodel/UEntity.java | 2 +- .../uprotocol/uri/datamodel/UResource.java | 2 +- .../eclipse/uprotocol/uri/datamodel/UUri.java | 2 +- .../eclipse/uprotocol/uri/datamodel/Uri.java | 48 ++++++ ...Serializer.java => LongUriSerializer.java} | 4 +- ...erializer.java => MicroUriSerializer.java} | 7 +- .../uri/serializer/UriSerializer.java | 4 +- .../uprotocol/uri/validator/UriValidator.java | 2 +- .../factory/CloudEventFactoryTest.java | 36 ++--- .../cloudevent/factory/UCloudEventTest.java | 2 +- .../CloudEventToJsonSerializerTest.java | 2 +- .../CloudEventToProtobufSerializerTest.java | 4 +- .../validate/CloudEventValidatorTest.java | 2 +- .../org/eclipse/uprotocol/rpc/RpcTest.java | 2 +- .../serializer/BytesUriSerializerTest.java | 48 +++--- .../serializer/StringUriSerializerTest.java | 142 +++++++++--------- .../uri/validator/UriValidatorTest.java | 26 ++-- .../validator/UAttributesValidatorTest.java | 12 +- 22 files changed, 221 insertions(+), 163 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java rename src/main/java/org/eclipse/uprotocol/uri/serializer/{StringUriSerializer.java => LongUriSerializer.java} (97%) rename src/main/java/org/eclipse/uprotocol/uri/serializer/{BytesUriSerializer.java => MicroUriSerializer.java} (94%) diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java index f7e02732..d5c2d8bc 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java @@ -152,7 +152,7 @@ public ValidationResult validateSink(CloudEvent cloudEvent) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateUEntityUri(String uri) { - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); return validateUEntityUri(Uri); } @@ -175,7 +175,7 @@ public static ValidationResult validateUEntityUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateTopicUri(String uri) { - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); return validateTopicUri(Uri); } @@ -206,7 +206,7 @@ public static ValidationResult validateTopicUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcTopicUri(String uri) { - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); return validateRpcTopicUri(Uri); } @@ -234,7 +234,7 @@ public static ValidationResult validateRpcTopicUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcMethod(String uri) { - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); ValidationResult validationResult = validateUEntityUri(Uri); if (validationResult.isFailure()){ return ValidationResult.failure(String.format("Invalid RPC method uri. %s", validationResult.getMessage())); diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java index 0685ee7a..9eacde54 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java @@ -28,16 +28,19 @@ import org.eclipse.uprotocol.utransport.datamodel.UPayload; /** - * Interface used by code generators found in https://github.com/eclipse-uprotocol/uprotocol-core-api - * to invoke a method to support RPC. + * RpcClient is an interface used by code generators for uProtocol services defined in proto files such as + * the core uProtocol services found in https://github.com/eclipse-uprotocol/uprotocol-core-api. the interface + * provides a clean contract for all transports to implement to be able to support RPC on their platform. Each + * platform MUST implement this interface. For more details please refer to + * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l2/README.adoc[RpcClient Specifications] */ public interface RpcClient { /** * Support for RPC method invocation. - * @param topic req.v1 CloudEvent. - * @param payload TODO - * @param attributes TODO + * @param topic topic of the method to be invoked (i.e. the name of the API we are calling). + * @param payload The request message to be sent to the server. + * @param attributes Metadata for the method invocation (i.e. priority, timeout, etc.) * @return Returns the CompletableFuture with the result or exception. */ CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes); diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java index d90b4542..6e95aa83 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java @@ -33,13 +33,15 @@ import org.eclipse.uprotocol.utransport.datamodel.UPayload; /** - * An interface that maps the returned value from uProtocol Layer 2 to the response in Layer3. + * RPC Wrapper is an interface that provides static methods to be able to wrap an RPC request with + * an RPC Response (uP-L2). APIs that return Message assumes that the payload is protobuf serialized + * com.google.protobuf.Any (USerializationHint.PROTOBUF) and will barf if anything else is passed */ public interface RpcMapper { /** - * Map a response of CompletableFuture<Any> from Link into a CompletableFuture containing the declared expected return type of the RPC method or an exception. - * @param responseFuture CompletableFuture<Any> response from Link. + * Map a response of CompletableFuture<UPayload> from Link into a CompletableFuture containing the declared expected return type of the RPC method or an exception. + * @param responseFuture CompletableFuture<UPayload> response from uTransport. * @param expectedClazz The class name of the declared expected return type of the RPC method. * @return Returns a CompletableFuture containing the declared expected return type of the RPC method or an exception. * @param The declared expected return type of the RPC method. diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 6f4960b8..74134107 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -32,7 +32,7 @@ * Devices will be grouped together into realms of Zone of Authority.
* An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ -public class UAuthority { +public class UAuthority implements Uri{ private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); /** @@ -242,4 +242,10 @@ public String toString() { '}'; } + + @Override + public boolean isEmpty() { + return isLocal(); + } + } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index fd47258a..e611ee87 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -31,7 +31,7 @@ * A uE that publishes events is a Service role.
* A uE that consumes events is an Application role. */ -public class UEntity { +public class UEntity implements Uri { private static final UEntity EMPTY = new UEntity("", null); private final String name; // uE Name diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 41ac9f2c..4104e19e 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -31,7 +31,7 @@ * An UResource is something that can be manipulated/controlled/exposed by a service. Resources are unique when prepended with UAuthority that represents the device and * UEntity that represents the service. */ -public class UResource { +public class UResource implements Uri { private static final UResource EMPTY = new UResource("", null,null, null); diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 74b113bd..193af0ab 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -35,7 +35,7 @@ * * */ -public class UUri { +public class UUri implements Uri { private static final UUri EMPTY = new UUri(UAuthority.empty(), UEntity.empty(), UResource.empty()); private final UAuthority uAuthority; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java new file mode 100644 index 00000000..45f9ec05 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java @@ -0,0 +1,48 @@ +package org.eclipse.uprotocol.uri.datamodel; + +/** + * Basic building blocks for all objects that are art of a uProtocol URI. The + * interface defines APIs that MUST be implemented in all objects. + */ +public interface Uri { + + /** + * Return true if the object is empty + * @return true if the object is empty + */ + public boolean isEmpty(); + + + /** + * Check if the passed object is equal to this object + * @param o The object to compare + * @return true if the passed object is equal to this object + */ + public boolean equals(Object o); + + /** + * Return the hash code of this object + * @return the hash code of this object + */ + public int hashCode(); + + /** + * Return the string representation of this object + * @return the string representation of this object + */ + public String toString(); + + /** + * Returns true if the object contains both names and ids (numbers) corresponding to the + * data inside of its belly. Return of true means that the object can be serialized to both + * long and micro uri format. + * @return Returns true if the object contains both names and ids (numbers) + */ + public boolean isResolved(); + + /** + * Returns true if the object contains names so that it can be serialized to long format. + * @return Returns true if the object contains names so that it can be serialized to long format. + */ + public boolean isLongForm(); +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java similarity index 97% rename from src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java rename to src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index 3212a64b..e347191b 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -30,10 +30,10 @@ import java.util.stream.Collectors; /** - * UUri Serializer that serializes a UUri to a string (long or long form) per + * UUri Serializer that serializes a UUri to a string (long format) per * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ -public class StringUriSerializer implements UriSerializer { +public class LongUriSerializer implements UriSerializer { /** * Serialize the UUri object Into a string in Long Form. diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java similarity index 94% rename from src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java rename to src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index 1be91792..c8879ea3 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -34,11 +34,10 @@ import java.util.Optional; /** - * UUri Factory used to build different types of UUri (long, short, micro), and UUri objects themselves - * for the various use cases found in uProtocol specifications. - * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + * UUri Serializer that serializes a UUri to a byte[] (micro format) per + * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ -public class BytesUriSerializer implements UriSerializer { +public class MicroUriSerializer implements UriSerializer { static final int LOCAL_MICRO_URI_LENGTH = 8; // local micro URI length diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index 3449479a..c36d8d6a 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -49,11 +49,11 @@ public interface UriSerializer { /** * Long form serializer */ - public static StringUriSerializer STRING = new StringUriSerializer(); + public static LongUriSerializer LONG = new LongUriSerializer(); /** * Micro form serializer */ - public static BytesUriSerializer BYTES = new BytesUriSerializer(); + public static MicroUriSerializer MICRO = new MicroUriSerializer(); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 4b3ea165..963ff5ea 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -72,7 +72,7 @@ public static UStatus validateRpcResponse(UUri uri) { * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validateLongUUri(String uri) { - final UUri uUri = UriSerializer.STRING.deserialize(uri); + final UUri uUri = UriSerializer.LONG.deserialize(uri); return validate(uUri); } diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index d9f487d7..322b95ee 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -53,7 +53,7 @@ public void test_create_base_cloud_event() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -95,7 +95,7 @@ public void test_create_base_cloud_event_with_datacontenttype_and_schema() { UEntity use = UEntity.fromName("body.access"); UUri ultifiUri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(ultifiUri); + String source = UriSerializer.LONG.serialize(ultifiUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -143,7 +143,7 @@ public void test_create_base_cloud_event_without_attributes() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -180,7 +180,7 @@ public void test_create_publish_cloud_event() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -214,12 +214,12 @@ public void test_create_notification_cloud_event() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // sink UEntity sinkUse = UEntity.fromName("petapp"); UUri sinkUri = new UUri(UAuthority.remote("com.gm.bo", "bo"), sinkUse, "OK"); - String sink = UriSerializer.STRING.serialize(sinkUri); + String sink = UriSerializer.LONG.serialize(sinkUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -256,13 +256,13 @@ public void test_create_request_cloud_event_from_local_use() { // Uri for the application requesting the RPC UEntity sourceUse = UEntity.fromName("petapp"); - String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); + String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -302,14 +302,14 @@ public void test_create_request_cloud_event_from_remote_use() { // Uri for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); UEntity sourceUse = new UEntity("petapp", 1); - String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); + String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -348,13 +348,13 @@ public void test_create_response_cloud_event_originating_from_local_use() { // Uri for the application requesting the RPC UEntity sourceUse = new UEntity("petapp", 1); - String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); + String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -395,14 +395,14 @@ public void test_create_response_cloud_event_originating_from_remote_use() { UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); UEntity sourceUse = UEntity.fromName("petapp"); - String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); + String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -442,13 +442,13 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use // Uri for the application requesting the RPC UEntity sourceUse = new UEntity("petapp", 1); - String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); + String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // additional attributes final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() @@ -487,14 +487,14 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); UEntity sourceUse = UEntity.fromName("petapp"); - String applicationUriForRPC = UriSerializer.STRING.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method Uri UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); - String serviceMethodUri = UriSerializer.STRING.serialize(methodUri); + String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // additional attributes diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java index 418790fa..0cc9694f 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java @@ -683,7 +683,7 @@ private CloudEventBuilder buildBaseCloudEventBuilderForTest() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java index 0d4a98dc..46abd512 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java @@ -168,7 +168,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java index 35cde75e..c878be42 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java @@ -58,7 +58,7 @@ public void test_serialize_and_desirialize_cloud_event_to_protobuf() { // build the source UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("Door", "front_left")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -148,7 +148,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index ca070406..db5f7fcd 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -1022,7 +1022,7 @@ private CloudEventBuilder buildBaseCloudEventBuilderForTest() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String source = UriSerializer.STRING.serialize(Uri); + String source = UriSerializer.LONG.serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 54b22811..5e83923d 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -542,7 +542,7 @@ private static UPayload buildUPayload() { } private static UUri buildTopic() { - return UriSerializer.STRING.deserialize("//vcu.vin/hartley/1/rpc.Raise"); + return UriSerializer.LONG.deserialize("//vcu.vin/hartley/1/rpc.Raise"); } private static UAttributes buildUAttributes() { diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java index 1f3720b6..6fea31fa 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java @@ -21,22 +21,22 @@ public class BytesUriSerializerTest { @DisplayName("Test serialize and deserialize empty content") public void test_empty() { UUri uri = UUri.empty(); - byte[] bytes = UriSerializer.BYTES.serialize(uri); + byte[] bytes = UriSerializer.MICRO.serialize(uri); assertEquals(bytes.length, 0); - UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + UUri uri2 = UriSerializer.MICRO.deserialize(bytes); assertTrue(uri2.isEmpty()); } @Test @DisplayName("Test serialize and deserialize null content") public void test_null() { - byte[] bytes = UriSerializer.BYTES.serialize(null); + byte[] bytes = UriSerializer.MICRO.serialize(null); assertEquals(bytes.length, 0); - UUri uri2 = UriSerializer.BYTES.deserialize(null); + UUri uri2 = UriSerializer.MICRO.deserialize(null); assertTrue(uri2.isEmpty()); } @@ -49,8 +49,8 @@ public void test_serialize_uri() { UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.BYTES.serialize(uri); - UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + byte[] bytes = UriSerializer.MICRO.serialize(uri); + UUri uri2 = UriSerializer.MICRO.deserialize(bytes); assertEquals(uri, uri2); } @@ -60,19 +60,19 @@ public void test_serialize_uri() { @DisplayName("Test serialize invalid UUris") public void test_serialize_invalid_uuris() throws UnknownHostException { UUri uri = new UUri(UAuthority.local(), UEntity.fromId(null, (short)1), UResource.empty()); - byte[] bytes = UriSerializer.BYTES.serialize(uri); + byte[] bytes = UriSerializer.MICRO.serialize(uri); assertEquals(bytes.length, 0); UUri uri2 = new UUri(UAuthority.local(), new UEntity("", null), UResource.forRpc("", (short)1)); - byte[] bytes2 = UriSerializer.BYTES.serialize(uri2); + byte[] bytes2 = UriSerializer.MICRO.serialize(uri2); assertEquals(bytes2.length, 0); UUri uri3 = new UUri(UAuthority.remote("null", "null"), new UEntity("", null), UResource.forRpc("", (short)1)); - byte[] bytes3 = UriSerializer.BYTES.serialize(uri3); + byte[] bytes3 = UriSerializer.MICRO.serialize(uri3); assertEquals(bytes3.length, 0); UUri uri4 = new UUri(UAuthority.remote("vcu", "vin", null), new UEntity("", null), UResource.forRpc("", (short)1)); - byte[] bytes4 = UriSerializer.BYTES.serialize(uri4); + byte[] bytes4 = UriSerializer.MICRO.serialize(uri4); assertEquals(bytes4.length, 0); } @@ -84,8 +84,8 @@ public void test_serialize_ipv4_uri() throws UnknownHostException { UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.BYTES.serialize(uri); - UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + byte[] bytes = UriSerializer.MICRO.serialize(uri); + UUri uri2 = UriSerializer.MICRO.deserialize(bytes); assertEquals(uri, uri2); } @@ -97,8 +97,8 @@ public void test_serialize_ipv6_uri() throws UnknownHostException { UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.BYTES.serialize(uri); - UUri uri2 = UriSerializer.BYTES.deserialize(bytes); + byte[] bytes = UriSerializer.MICRO.serialize(uri); + UUri uri2 = UriSerializer.MICRO.deserialize(bytes); assertEquals(uri, uri2); } @@ -109,54 +109,54 @@ public void test_deserialize_with_missing_information() throws UnknownHostExcept UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.BYTES.serialize(uri); + byte[] bytes = UriSerializer.MICRO.serialize(uri); // invalid version byte[] byte1 = Arrays.copyOf(bytes, bytes.length); byte1[0] = 0x0; - UUri uri1 = UriSerializer.BYTES.deserialize(byte1); + UUri uri1 = UriSerializer.MICRO.deserialize(byte1); assertTrue(uri1.isEmpty()); // Invalid type byte[] byte2 = Arrays.copyOf(bytes, bytes.length); byte2[1] = Byte.MAX_VALUE; - UUri uri2 = UriSerializer.BYTES.deserialize(byte2); + UUri uri2 = UriSerializer.MICRO.deserialize(byte2); assertTrue(uri2.isEmpty()); // Wrong size (local) byte[] byte3 = new byte[] {0x1, 0x0, 0x0, 0x0}; - UUri uri3 = UriSerializer.BYTES.deserialize(byte3); + UUri uri3 = UriSerializer.MICRO.deserialize(byte3); assertTrue(uri3.isEmpty()); // Wrong size (ipv4) byte[] byte4 = new byte[] {0x1, 0x1, 0x0, 0x0}; - UUri uri4 = UriSerializer.BYTES.deserialize(byte4); + UUri uri4 = UriSerializer.MICRO.deserialize(byte4); assertTrue(uri4.isEmpty()); // Wrong size (ipv6) byte[] byte5 = new byte[] {0x1, 0x1, 0x0, 0x0}; - UUri uri5 = UriSerializer.BYTES.deserialize(byte5); + UUri uri5 = UriSerializer.MICRO.deserialize(byte5); assertTrue(uri5.isEmpty()); // Right local size (local) byte[] byte6 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri6 = UriSerializer.BYTES.deserialize(byte6); + UUri uri6 = UriSerializer.MICRO.deserialize(byte6); assertFalse(uri6.isEmpty()); // IPv4 type local size byte[] byte7 = new byte[] {0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri7 = UriSerializer.BYTES.deserialize(byte7); + UUri uri7 = UriSerializer.MICRO.deserialize(byte7); assertTrue(uri7.isEmpty()); // IPv6 type local size byte[] byte8 = new byte[] {0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri8 = UriSerializer.BYTES.deserialize(byte8); + UUri uri8 = UriSerializer.MICRO.deserialize(byte8); assertTrue(uri8.isEmpty()); // Local type but too large byte[] byte9 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri9 = UriSerializer.BYTES.deserialize(byte9); + UUri uri9 = UriSerializer.MICRO.deserialize(byte9); assertTrue(uri9.isEmpty()); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java index b91205e3..6c45d1af 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java @@ -16,16 +16,16 @@ public class StringUriSerializerTest { @DisplayName("Test using the serializers") public void test_using_the_serializers() { final UUri uri = new UUri(UAuthority.local(), UEntity.fromName("hartley"), UResource.forRpc("raise")); - final String strUri = UriSerializer.STRING.serialize(uri); + final String strUri = UriSerializer.LONG.serialize(uri); assertEquals("/hartley//rpc.raise", strUri); - final UUri uri2 = UriSerializer.STRING.deserialize(strUri); + final UUri uri2 = UriSerializer.LONG.deserialize(strUri); assertTrue(uri.equals(uri2)); } @Test @DisplayName("Test parse uProtocol uri that is null") public void test_parse_protocol_uri_when_is_null() { - UUri Uri = UriSerializer.STRING.deserialize(null); + UUri Uri = UriSerializer.LONG.deserialize(null); assertTrue(Uri.isEmpty()); } @@ -34,7 +34,7 @@ public void test_parse_protocol_uri_when_is_null() { @DisplayName("Test parse uProtocol uri that is empty string") public void test_parse_protocol_uri_when_is_empty_string() { String uri = ""; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.isEmpty()); } @@ -42,7 +42,7 @@ public void test_parse_protocol_uri_when_is_empty_string() { @DisplayName("Test parse uProtocol uri with schema and slash") public void test_parse_protocol_uri_with_schema_and_slash() { String uri = "/"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -52,7 +52,7 @@ public void test_parse_protocol_uri_with_schema_and_slash() { @DisplayName("Test parse uProtocol uri with schema and double slash") public void test_parse_protocol_uri_with_schema_and_double_slash() { String uri = "//"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -62,7 +62,7 @@ public void test_parse_protocol_uri_with_schema_and_double_slash() { @DisplayName("Test parse uProtocol uri with schema and 3 slash and something") public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { String uri = "///body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -74,7 +74,7 @@ public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 4 slash and something") public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { String uri = "////body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().name().isBlank()); @@ -86,7 +86,7 @@ public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 5 slash and something") public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { String uri = "/////body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().isEmpty()); @@ -100,7 +100,7 @@ public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 6 slash and something") public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { String uri = "//////body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -110,7 +110,7 @@ public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { @DisplayName("Test parse uProtocol uri with local service no version") public void test_parse_protocol_uri_with_local_service_no_version() { String uri = "/body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -122,7 +122,7 @@ public void test_parse_protocol_uri_with_local_service_no_version() { @DisplayName("Test parse uProtocol uri with local service with version") public void test_parse_protocol_uri_with_local_service_with_version() { String uri = "/body.access/1"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -135,7 +135,7 @@ public void test_parse_protocol_uri_with_local_service_with_version() { @DisplayName("Test parse uProtocol uri with local service no version with resource name only") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_name_only() { String uri = "/body.access//door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -149,7 +149,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource name only") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_name_only() { String uri = "/body.access/1/door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -164,7 +164,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol uri with local service no version with resource and instance only") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance() { String uri = "/body.access//door.front_left"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -179,7 +179,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource and instance only") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_message() { String uri = "/body.access/1/door.front_left"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -195,7 +195,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol uri with local service no version with resource with instance and message") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance_and_message() { String uri = "/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -211,7 +211,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource with instance and message") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_instance_and_message() { String uri = "/body.access/1/door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -228,7 +228,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol RPC uri with local service no version") public void test_parse_protocol_rpc_uri_with_local_service_no_version() { String uri = "/petapp//rpc.response"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); @@ -243,7 +243,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_no_version() { @DisplayName("Test parse uProtocol RPC uri with local service with version") public void test_parse_protocol_rpc_uri_with_local_service_with_version() { String uri = "/petapp/1/rpc.response"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); @@ -259,7 +259,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_with_version() { @DisplayName("Test parse uProtocol uri with remote service only device no domain") public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() { String uri = "//VCU"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -272,7 +272,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() @DisplayName("Test parse uProtocol uri with remote service only device and domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() { String uri = "//VCU.MY_CAR_VIN"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -286,7 +286,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() @DisplayName("Test parse uProtocol uri with remote service only device and cloud domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_domain() { String uri = "//cloud.uprotocol.example.com"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -300,7 +300,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_do @DisplayName("Test parse uProtocol uri with remote service no version") public void test_parse_protocol_uri_with_remote_service_no_version() { String uri = "//VCU.MY_CAR_VIN/body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -315,7 +315,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version() { @DisplayName("Test parse uProtocol uri with remote cloud service no version") public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { String uri = "//cloud.uprotocol.example.com/body.access"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -330,7 +330,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { @DisplayName("Test parse uProtocol uri with remote service with version") public void test_parse_protocol_uri_with_remote_service_with_version() { String uri = "//VCU.MY_CAR_VIN/body.access/1"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -346,7 +346,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version() { @DisplayName("Test parse uProtocol uri with remote cloud service with version") public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { String uri = "//cloud.uprotocol.example.com/body.access/1"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -362,7 +362,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { @DisplayName("Test parse uProtocol uri with remote service no version with resource name only") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access//door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -379,7 +379,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with remote cloud service no version with resource name only") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access//door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -396,7 +396,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re @DisplayName("Test parse uProtocol uri with remote service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -414,7 +414,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with remote cloud service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access/1/door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -432,7 +432,7 @@ public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_ @DisplayName("Test parse uProtocol uri with remote service no version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -450,7 +450,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with remote service with version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -469,7 +469,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with remote service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -488,7 +488,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with remote cloud service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -507,7 +507,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re @DisplayName("Test parse uProtocol uri with remote service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -527,7 +527,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with remote cloud service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access/1/door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -547,7 +547,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_ @DisplayName("Test parse uProtocol uri with remote service with version with resource with message when there is only device, no domain") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_with_message_device_no_domain() { String uri = "//VCU/body.access/1/door.front_left"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -565,7 +565,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol RPC uri with remote service no version") public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { String uri = "//bo.cloud/petapp//rpc.response"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("bo", Uri.uAuthority().device().get()); @@ -583,7 +583,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { @DisplayName("Test parse uProtocol RPC uri with remote service with version") public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { String uri = "//bo.cloud/petapp/1/rpc.response"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("bo", Uri.uAuthority().device().get()); @@ -601,7 +601,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { @Test @DisplayName("Test Create a uProtocol URI from null") public void test_build_protocol_uri_from__uri_when__uri_isnull() { - String uProtocolUri = UriSerializer.STRING.serialize(null); + String uProtocolUri = UriSerializer.LONG.serialize(null); assertEquals("", uProtocolUri); } @@ -609,7 +609,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isnull() { @DisplayName("Test Create a uProtocol URI from an empty URI Object") public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { UUri Uri = UUri.empty(); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("", uProtocolUri); } @@ -618,7 +618,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { UEntity use = UEntity.empty(); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/", uProtocolUri); } @@ -627,7 +627,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access", uProtocolUri); } @@ -636,7 +636,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1", uProtocolUri); } @@ -645,7 +645,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access//door", uProtocolUri); } @@ -654,7 +654,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1/door", uProtocolUri); } @@ -663,7 +663,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access//door.front_left", uProtocolUri); } @@ -672,7 +672,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1/door.front_left", uProtocolUri); } @@ -681,7 +681,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access//door.front_left#Door", uProtocolUri); } @@ -690,7 +690,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_message() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1/door.front_left#Door", uProtocolUri); } @@ -699,7 +699,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access", uProtocolUri); } @@ -708,7 +708,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_device_with_domain_with_service_no_version() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//my_car_vin/body.access", uProtocolUri); } @@ -717,7 +717,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri); } @@ -726,7 +726,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.empty()); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri); } @@ -735,7 +735,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -744,7 +744,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door", uProtocolUri); } @@ -753,7 +753,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left", uProtocolUri); } @@ -762,7 +762,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1/door.front_left", uProtocolUri); } @@ -771,7 +771,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left", uProtocolUri); } @@ -780,7 +780,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { UEntity use = new UEntity("body.access", 1); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left#Door", uProtocolUri); } @@ -789,7 +789,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_message() { UEntity use = UEntity.fromName("body.access"); UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left#Door", uProtocolUri); } @@ -798,7 +798,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_local() { UAuthority uAuthority = UAuthority.local(); UEntity use = new UEntity("petapp", 1); - String uProtocolUri = UriSerializer.STRING.serialize(UUri.rpcResponse(uAuthority, use)); + String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("/petapp/1/rpc.response", uProtocolUri); } @@ -807,7 +807,7 @@ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_remote() { UAuthority uAuthority = UAuthority.remote("cloud", "uprotocol.example.com"); UEntity use = UEntity.fromName("petapp"); - String uProtocolUri = UriSerializer.STRING.serialize(UUri.rpcResponse(uAuthority, use)); + String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("//cloud.uprotocol.example.com/petapp//rpc.response", uProtocolUri); } @@ -818,7 +818,7 @@ public void test_build_protocol_uri_from_parts_when_they_are_null() { UEntity uSoftwareEntity = null; UResource uResource = null; UUri Uri = new UUri(uAuthority, uSoftwareEntity, uResource); - String uProtocolUri = UriSerializer.STRING.serialize(Uri); + String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("", uProtocolUri); } @@ -828,7 +828,7 @@ public void test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authori UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); - String uProtocolUri = UriSerializer.STRING.serialize(new UUri(uAuthority, use, uResource)); + String uProtocolUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -838,7 +838,7 @@ public void test_custom_scheme_no_scheme_empty() { UAuthority uAuthority = null; UEntity uSoftwareEntity = null; UResource uResource = null; - String customUri = UriSerializer.STRING.serialize(new UUri(uAuthority, uSoftwareEntity, uResource)); + String customUri = UriSerializer.LONG.serialize(new UUri(uAuthority, uSoftwareEntity, uResource)); assertTrue(customUri.isEmpty()); } @@ -848,7 +848,7 @@ public void test_custom_scheme_no_scheme() { UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); - String ucustomUri = UriSerializer.STRING.serialize(new UUri(uAuthority, use, uResource)); + String ucustomUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", ucustomUri); } @@ -856,7 +856,7 @@ public void test_custom_scheme_no_scheme() { @DisplayName("Test parse local uProtocol uri with custom scheme") public void test_parse_local_protocol_uri_with_custom_scheme() { String uri = "custom:/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -873,7 +873,7 @@ public void test_parse_local_protocol_uri_with_custom_scheme() { public void test_parse_remote_protocol_uri_with_custom_scheme() { String uri = "custom://vcu.vin/body.access//door.front_left#Door"; String uri2 = "//vcu.vin/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.STRING.deserialize(uri); + UUri Uri = UriSerializer.LONG.deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -886,7 +886,7 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { assertEquals("front_left", Uri.uResource().instance().get()); assertTrue(Uri.uResource().message().isPresent()); assertEquals("Door", Uri.uResource().message().get()); - assertEquals(uri2, UriSerializer.STRING.serialize(Uri)); + assertEquals(uri2, UriSerializer.LONG.serialize(Uri)); } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java index 79fc2ee6..4036d9f2 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -41,7 +41,7 @@ class UriValidatorTest { @Test @DisplayName("Test validate blank uri") public void test_validate_blank_uri() { - final UUri uri = UriSerializer.STRING.deserialize(null); + final UUri uri = UriSerializer.LONG.deserialize(null); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -51,7 +51,7 @@ public void test_validate_blank_uri() { @Test @DisplayName("Test validate uri with no device name") public void test_validate_uri_with_no_entity_name() { - final UUri uri = UriSerializer.STRING.deserialize("//"); + final UUri uri = UriSerializer.LONG.deserialize("//"); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -61,7 +61,7 @@ public void test_validate_uri_with_no_entity_name() { @Test @DisplayName("Test validate uri with uEntity") public void test_validate_uri_with_uEntity() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley"); + final UUri uri = UriSerializer.LONG.deserialize("/hartley"); final UStatus status = UriValidator.validate(uri); assertEquals(UStatus.ok(), status); } @@ -69,7 +69,7 @@ public void test_validate_uri_with_uEntity() { @Test @DisplayName("Test validate with malformed URI") public void test_validate_with_malformed_uri() { - final UUri uri = UriSerializer.STRING.deserialize("hartley"); + final UUri uri = UriSerializer.LONG.deserialize("hartley"); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -90,7 +90,7 @@ public void test_validate_with_blank_uentity_name_uri() { @Test @DisplayName("Test validateRpcMethod with valid URI") public void test_validateRpcMethod_with_valid_uri() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.echo"); + final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(UStatus.ok(), status); } @@ -98,7 +98,7 @@ public void test_validateRpcMethod_with_valid_uri() { @Test @DisplayName("Test validateRpcMethod with valid URI") public void test_validateRpcMethod_with_invalid_uri() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley/echo"); + final UUri uri = UriSerializer.LONG.deserialize("/hartley/echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.msg()); @@ -107,7 +107,7 @@ public void test_validateRpcMethod_with_invalid_uri() { @Test @DisplayName("Test validateRpcMethod with malformed URI") public void test_validateRpcMethod_with_malformed_uri() { - final UUri uri = UriSerializer.STRING.deserialize("hartley"); + final UUri uri = UriSerializer.LONG.deserialize("hartley"); final UStatus status = UriValidator.validateRpcMethod(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -117,7 +117,7 @@ public void test_validateRpcMethod_with_malformed_uri() { @Test @DisplayName("Test validateRpcResponse with valid URI") public void test_validateRpcResponse_with_valid_uri() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.response"); + final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.response"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(UStatus.ok(), status); } @@ -125,7 +125,7 @@ public void test_validateRpcResponse_with_valid_uri() { @Test @DisplayName("Test validateRpcResponse with malformed URI") public void test_validateRpcResponse_with_malformed_uri() { - final UUri uri = UriSerializer.STRING.deserialize("hartley"); + final UUri uri = UriSerializer.LONG.deserialize("hartley"); final UStatus status = UriValidator.validateRpcResponse(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); @@ -135,7 +135,7 @@ public void test_validateRpcResponse_with_malformed_uri() { @Test @DisplayName("Test validateRpcResponse with rpc type") public void test_validateRpcResponse_with_rpc_type() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley//dummy.wrong"); + final UUri uri = UriSerializer.LONG.deserialize("/hartley//dummy.wrong"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); @@ -144,7 +144,7 @@ public void test_validateRpcResponse_with_rpc_type() { @Test @DisplayName("Test validateRpcResponse with invalid rpc response type") public void test_validateRpcResponse_with_invalid_rpc_response_type() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.wrong"); + final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.wrong"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); @@ -153,8 +153,8 @@ public void test_validateRpcResponse_with_invalid_rpc_response_type() { @Test @DisplayName("Test validateLongUUri with valid URI") public void test_validateLongUUri_with_valid_uri() { - final UUri uri = UriSerializer.STRING.deserialize("/hartley//rpc.echo"); - final UStatus status = UriValidator.validateLongUUri(UriSerializer.STRING.serialize(uri)); + final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.echo"); + final UStatus status = UriValidator.validateLongUUri(UriSerializer.LONG.serialize(uri)); assertEquals(UStatus.ok(), status); } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index c13fa058..d3a55184 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -763,7 +763,7 @@ public void test_validating_valid_id_attribute() { @Test @DisplayName("test validating invalid sink attribute") public void test_validating_invalid_sink_attribute() { - final UUri uri = UriSerializer.STRING.deserialize("//"); + final UUri uri = UriSerializer.LONG.deserialize("//"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); @@ -778,7 +778,7 @@ public void test_validating_invalid_sink_attribute() { @Test @DisplayName("test validating valid sink attribute") public void test_validating_valid_sink_attribute() { - final UUri uri = UriSerializer.STRING.deserialize("/haartley/1"); + final UUri uri = UriSerializer.LONG.deserialize("/haartley/1"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); @@ -894,7 +894,7 @@ public void test_validating_valid_commstatus_attribute() { @Test @DisplayName("test validating request message types") public void test_validating_request_message_types() { - final UUri sink = UriSerializer.STRING.deserialize("/hartley/1/rpc.response"); + final UUri sink = UriSerializer.LONG.deserialize("/hartley/1/rpc.response"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) @@ -931,7 +931,7 @@ public void test_validating_request_validator_with_wrong_bad_ttl() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) - .withSink(UriSerializer.STRING.deserialize("/hartley/1/rpc.response")) + .withSink(UriSerializer.LONG.deserialize("/hartley/1/rpc.response")) .withTtl(-1) .build(); @@ -949,7 +949,7 @@ public void test_validating_response_validator_with_wrong_bad_ttl() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) - .withSink(UriSerializer.STRING.deserialize("/hartley/1/rpc.response")) + .withSink(UriSerializer.LONG.deserialize("/hartley/1/rpc.response")) .withTtl(-1) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); @@ -969,7 +969,7 @@ public void test_validating_response_validator_with_bad_reqid() { final UUID id = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) - .withSink(UriSerializer.STRING.deserialize("/hartley/1/rpc.response")) + .withSink(UriSerializer.LONG.deserialize("/hartley/1/rpc.response")) .withTtl(100) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); From a33b7890b13f31381aa003e8f50e9be252c38da3 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Mon, 18 Sep 2023 19:44:53 +0300 Subject: [PATCH 34/52] working on UUri --- .../validate/CloudEventValidator.java | 34 +-- .../uprotocol/uri/datamodel/UAuthority.java | 148 ++++++------ .../uprotocol/uri/datamodel/UEntity.java | 147 +++++++----- .../uprotocol/uri/datamodel/UResource.java | 217 ++++++++---------- .../eclipse/uprotocol/uri/datamodel/UUri.java | 77 ++++--- .../eclipse/uprotocol/uri/datamodel/Uri.java | 48 ---- .../uprotocol/uri/datamodel/UriPart.java | 33 +++ .../uri/serializer/LongUriSerializer.java | 37 ++- .../uri/serializer/MicroUriSerializer.java | 4 +- .../uprotocol/uri/validator/UriValidator.java | 18 +- .../utransport/datamodel/UAttributes.java | 2 +- .../validate/UAttributesValidator.java | 2 +- .../factory/CloudEventFactoryTest.java | 44 ++-- .../validate/CloudEventValidatorTest.java | 142 ++++++------ .../uri/datamodel/UAuthorityTest.java | 38 +-- .../uprotocol/uri/datamodel/UUriTest.java | 34 +-- ...t.java => BytesUriSerializerTestPart.java} | 12 +- ....java => StringUriSerializerTestPart.java} | 100 ++++---- ...torTest.java => UriPartValidatorTest.java} | 18 +- .../utransport/datamodel/UAttributeTest.java | 12 +- .../validator/UAttributesValidatorTest.java | 46 ++-- 21 files changed, 604 insertions(+), 609 deletions(-) delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java create mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java rename src/test/java/org/eclipse/uprotocol/uri/serializer/{BytesUriSerializerTest.java => BytesUriSerializerTestPart.java} (90%) rename src/test/java/org/eclipse/uprotocol/uri/serializer/{StringUriSerializerTest.java => StringUriSerializerTestPart.java} (89%) rename src/test/java/org/eclipse/uprotocol/uri/validator/{UriValidatorTest.java => UriPartValidatorTest.java} (92%) diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java index d5c2d8bc..301dbc1e 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java @@ -146,7 +146,7 @@ public ValidationResult validateSink(CloudEvent cloudEvent) { } /** - * Validate an Uri for an Software Entity must have an authority in the case of a remote uri, and must contain + * Validate an UriPart for an Software Entity must have an authority in the case of a microRemote uri, and must contain * the name of the USE. * @param uri uri string to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. @@ -160,18 +160,18 @@ public static ValidationResult validateUEntityUri(UUri Uri) { final UAuthority uAuthority = Uri.uAuthority(); if (uAuthority.isMarkedRemote()) { if (uAuthority.device().isEmpty()) { - return ValidationResult.failure("Uri is configured to be remote and is missing uAuthority device name."); + return ValidationResult.failure("UriPart is configured to be microRemote and is missing uAuthority device name."); } } if (Uri.uEntity().name().isBlank()) { - return ValidationResult.failure("Uri is missing uSoftware Entity name."); + return ValidationResult.failure("UriPart is missing uSoftware Entity name."); } return ValidationResult.success(); } /** - * Validate a Uri that is to be used as a topic in publish scenarios for events such as publish, file and notification. - * @param uri String Uri to validate. + * Validate a UriPart that is to be used as a topic in publish scenarios for events such as publish, file and notification. + * @param uri String UriPart to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateTopicUri(String uri) { @@ -180,8 +180,8 @@ public static ValidationResult validateTopicUri(String uri) { } /** - * Validate a Uri that is to be used as a topic in publish scenarios for events such as publish, file and notification. - * @param Uri Uri to validate. + * Validate a UriPart that is to be used as a topic in publish scenarios for events such as publish, file and notification. + * @param Uri UriPart to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateTopicUri(UUri Uri) { @@ -191,18 +191,18 @@ public static ValidationResult validateTopicUri(UUri Uri) { } final UResource uResource = Uri.uResource(); if (uResource.name().isBlank()) { - return ValidationResult.failure("Uri is missing uResource name."); + return ValidationResult.failure("UriPart is missing uResource name."); } if (uResource.message().isEmpty()) { - return ValidationResult.failure("Uri is missing Message information."); + return ValidationResult.failure("UriPart is missing Message information."); } return ValidationResult.success(); } /** - * Validate a Uri that is meant to be used as the application response topic for rpc calls.
+ * Validate a UriPart that is meant to be used as the application response topic for rpc calls.
* Used in Request source values and Response sink values. - * @param uri String Uri to validate. + * @param uri String UriPart to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcTopicUri(String uri) { @@ -211,8 +211,8 @@ public static ValidationResult validateRpcTopicUri(String uri) { } /** - * Validate an Uri that is meant to be used as the application response topic for rpc calls.
- * @param Uri Uri to validate. + * Validate an UriPart that is meant to be used as the application response topic for rpc calls.
+ * @param Uri UriPart to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcTopicUri(UUri Uri) { @@ -223,14 +223,14 @@ public static ValidationResult validateRpcTopicUri(UUri Uri) { final UResource uResource = Uri.uResource(); String topic = String.format("%s.%s", uResource.name(), uResource.instance().isPresent() ? uResource.instance().get() : "" ); if (!"rpc.response".equals(topic)) { - return ValidationResult.failure("Invalid RPC uri application response topic. Uri is missing rpc.response."); + return ValidationResult.failure("Invalid RPC uri application response topic. UriPart is missing rpc.response."); } return ValidationResult.success(); } /** - * Validate a Uri that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. - * @param uri String Uri to validate. + * Validate a UriPart that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. + * @param uri String UriPart to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcMethod(String uri) { @@ -241,7 +241,7 @@ public static ValidationResult validateRpcMethod(String uri) { } final UResource uResource = Uri.uResource(); if (!uResource.isRPCMethod()) { - return ValidationResult.failure("Invalid RPC method uri. Uri should be the method to be called, or method from response."); + return ValidationResult.failure("Invalid RPC method uri. UriPart should be the method to be called, or method from response."); } return ValidationResult.success(); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 74134107..154e97bd 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -27,53 +27,49 @@ import org.apache.commons.validator.routines.InetAddressValidator; /** - * Data representation of an Authority.
An Authority consists of a device and a domain.
+ * Data representation of an Authority.
An Authority consists of a device and a domain.
* Device and domain names are used as part of the URI for device and service discovery.
* Devices will be grouped together into realms of Zone of Authority.
* An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ -public class UAuthority implements Uri{ - private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); +public class UAuthority implements UriPart { + private final static UAuthority EMPTY = new UAuthority(null, null, null, false, false); /** * A device is a logical independent representation of a service bus in different execution environments.
- * Devices will be grouped together into realms of Zone of Authority. + * Devices will be grouped together into realms of Zone of Authority. */ private final String device; /** - * The domain an software entity is deployed on, such as vehicle or backoffice.
+ * The domain a software entity is deployed on, such as vehicle or backoffice.
* Vehicle Domain name MUST be that of the vehicle VIN.
* A domain name is an identification string that defines a realm of administrative autonomy, authority or control within the Internet. */ private final String domain; /** - * An Uri starting with // is a remote configuration of a URI, and we mark the uAuthority implicitly as remote. + * An UAuthority starting with // is a remote configuration of a URI, and we mark the uAuthority implicitly as remote. */ private final boolean markedRemote; - /** * The device IP address. */ private final InetAddress address; /** - * Indicates that the UUri contains both address and name and - * the name is not the string version of the IP address + * Indicates that this UAuthority has already been resolved. */ private final boolean markedResolved; - /** - * Constructor. - * @param device The device an software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). - * @param domain The domain an software entity is deployed on, such as vehicle or backoffice. + * Constructor for building a UAuthority. + * @param device The device a software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). + * @param domain The domain a software entity is deployed on, such as vehicle or backoffice. * @param address The device IP address. - * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. Used for validation. - * @param addressName Indicates if the device name is an IP address - * @param markedResolved Indicates if the UAuthority contains both address and names meaning the UAuthority is resolved. + * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. + * @param markedResolved Indicates that this uResource was populated with intent of having all data. */ private UAuthority(String device, String domain, InetAddress address, boolean markedRemote, boolean markedResolved) { this.device = device == null ? null : device.toLowerCase(); @@ -83,105 +79,85 @@ private UAuthority(String device, String domain, InetAddress address, boolean ma this.markedResolved = markedResolved; } - /** * Static factory method for creating a local authority.
* A local uri does not contain an authority and looks like this: *
 :<service>/<version>/<resource>#<Message> 
- * @return Returns a local altifi authority that has no domain or device information. + * @return Returns a local uAuthority that has no domain, device, or ip address information. */ public static UAuthority local() { return EMPTY; } /** - * Static factory method for creating a remote authority.
- * A remote uri contains an authority and looks like this: + * Static factory method for creating a remote authority using the long representation.
+ * An uri with a long representation of uAUthority can be serialized as follows: *
 //<device>.<domain>/<service>/<version>/<resource>#<Message> 
- * @param device The device an software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). - * @param domain The domain an software entity is deployed on, such as vehicle or backoffice. Vehicle Domain name MUST be that of the vehicle VIN. - * @return returns a remote authority that contains the device and the domain. + * @param device The device a software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). + * @param domain The domain a software entity is deployed on, such as vehicle or backoffice. Vehicle Domain name MUST be that of the vehicle VIN. + * @return Returns a uAuthority that contains the device and the domain and can be serialized in long UUri format. */ - public static UAuthority remote(String device, String domain) { - return remote(device, domain, null); + public static UAuthority longRemote(String device, String domain) { + return new UAuthority(device, domain, null, true, false); } /** - * Static factory method for creating a remote authority.
- * @param address The device an software entity is deployed on - * @return returns a remote authority that contains the device and the domain. + * Static factory method for creating a remote authority using the micro representation.
+ * @param address The ip address of the device a software entity is deployed on. + * @return Returns a uAuthority that contains only the internet address of the device, and can be serialized in micro UUri format. */ - public static UAuthority remote(InetAddress address) { - return remote(null, null, address); + public static UAuthority microRemote(InetAddress address) { + return new UAuthority(null, null, address, true, false); } - /** - * Static factory method for creating a remote authority using device, domain, and address.
- * @param device The device name - * @param domain The domain name - * @param address the IP address for the device - * @return returns a remote authority that contains the device and the domain. + * Static factory method for creating a remote authority that is completely resolved with name, device and ip address of the device.
+ * @param device The device name for long serialization of UUri. + * @param domain The domain name for long serialization of UUri. + * @param address the IP address for the device, for micro serialization of UUri. + * @return Returns a uAuthority that contains all resolved data and so can be serialized into a long UUri or a micro UUri. */ - public static UAuthority remote(String device, String domain, InetAddress address) { - InetAddress addr = address; - boolean markedResolved = device != null && address != null; - - // Try and set the address based on device name if the name is the string - // representation of an ip address. For this we need to mark it explicitly not resolved - if ( (device != null) && (addr == null) ) { - try { - if (InetAddressValidator.getInstance().isValid(device)) { - addr = InetAddress.getByName(device); - markedResolved = false; - } else { - addr = null; - } - } catch (Exception e) { - throw new IllegalArgumentException("Invalid device name: " + device, e); - } - } - - return new UAuthority(device, domain, addr, true, markedResolved); + public static UAuthority resolvedRemote(String device, String domain, InetAddress address) { + boolean resolved = device != null && !device.isBlank() && address != null; + return new UAuthority(device, domain, address, true, resolved); } /** - * Static factory method for creating an empty authority, to avoid working with null
- * @return Returns an empty authority that has no domain or device information. + * Static factory method for creating an empty uAuthority, to avoid working with null
+ * @return Returns an empty authority that has no domain, device, or device ip address information. */ public static UAuthority empty() { return EMPTY; } /** - * @return returns true if this authority is remote, meaning it contains a device or a domain. + * @return Returns true if this uAuthority is remote, meaning it contains information for long UUri or micro UUri. */ public boolean isRemote() { - return domain().isPresent() || device().isPresent(); + return isMarkedRemote(); } /** - * @return returns true if this authority is local, meaning does not contain a device or a domain. + * @return returns true if this uAuthority is local, meaning does not contain a device/domain for long UUri or information for micro UUri. */ public boolean isLocal() { - return domain().isEmpty() && device().isEmpty(); + return domain().isEmpty() && device().isEmpty() && address().isEmpty(); } /** - * @return Returns the device an software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). + * @return Returns the device a software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). */ public Optional device() { return device == null || device.isBlank() ? Optional.empty() : Optional.of(device); } /** - * @return Returns the domain an software entity is deployed on, such as vehicle or backoffice. + * @return Returns the domain a software entity is deployed on, such as vehicle or backoffice. */ public Optional domain() { return domain == null || domain.isBlank() ? Optional.empty() : Optional.of(domain); } - /** * @return Returns the device IP address. */ @@ -197,39 +173,49 @@ public boolean isMarkedRemote() { } /** - * Returns true if the UAuthority was tagged as resolved meaning the name and address are present and - * the name is NOT the string version of the IP address. *NOTE:* there is no way to know if the address is - * in fact a valid DNS address for the device+domain name so we will assume it is. - * @return Returns true if UAuthority contains both address and name. + * Returns true if the UAuthority was tagged as resolved meaning the name values and the ip address of the device are present. + * @return Returns true if UAuthority is resolved with all the information. */ + @Override public boolean isResolved() { return markedResolved; } /** - * Check if the UAuthority contains Long form URI (i.e. names). It will be long form - * if the UAuthority is resolved (meaning it has id and names) or there is no address since - * it has to has to have a device name. - * @return Returns true if the UAuthority contains Long form URI information (names) + * Check if the UAuthority can be used to serialize a long UUri. + * @return Returns true if the UAuthority can be used to serialize a long UUri. */ + @Override public boolean isLongForm() { - return isResolved() || !address().isPresent(); + return device().isPresent(); } + /** + * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. + * @return Returns true if the Uri part can be serialized into micro form. + */ + @Override + public boolean isMicroForm() { + return address().isPresent(); + } + + @Override + public boolean isEmpty() { + return isLocal(); + } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UAuthority that = (UAuthority) o; - return markedRemote == that.markedRemote && Objects.equals(device, that.device) - && Objects.equals(domain, that.domain) && Objects.equals(address, that.address) - && markedResolved == that.markedResolved ; + return markedRemote == that.markedRemote && markedResolved == that.markedResolved && Objects.equals(device, that.device) + && Objects.equals(domain, that.domain) && Objects.equals(address, that.address); } @Override public int hashCode() { - return Objects.hash(device, domain, address, markedRemote, markedResolved); + return Objects.hash(device, domain, markedRemote, address, markedResolved); } @Override @@ -242,10 +228,4 @@ public String toString() { '}'; } - - @Override - public boolean isEmpty() { - return isLocal(); - } - } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index e611ee87..2a5e9880 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -26,63 +26,80 @@ /** * Data representation of an Software Entity - uE
- * An Software Entity is a piece of software deployed somewhere on a uDevice.
- * The Software Entity is used in the source and sink parts of communicating software.
+ * An Software Entity is a piece of software deployed somewhere on a uDevice.
+ * The Software Entity is used in the source and sink parts of communicating software.
* A uE that publishes events is a Service role.
* A uE that consumes events is an Application role. */ -public class UEntity implements Uri { - private static final UEntity EMPTY = new UEntity("", null); +public class UEntity implements UriPart { + private static final UEntity EMPTY = new UEntity("", null, null, false); private final String name; // uE Name private final Integer version; // uE Major Version private final Short id; // uE ID + private final boolean markedResolved; // Indicates that this UAuthority has already been resolved. /** - * Build an Software Entity that represents a communicating piece of software. - * @param name The name of the software such as petpp or body.access. + * Build a Software Entity that represents a communicating piece of software. + * @param name The name of the software such as petapp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. + * @param id A numeric identifier for the software entity. + * @param markedResolved Indicates that this uResource was populated with intent of having all data. */ - public UEntity(String name, Integer version, Short id) { + private UEntity(String name, Integer version, Short id, boolean markedResolved) { Objects.requireNonNull(name, " Software Entity must have a name"); this.name = name; this.id = id; this.version = version; + this.markedResolved = markedResolved; + } + + public static UEntity resolvedFormat(String name, Integer version, Short id) { + boolean resolved = !name.isEmpty() && version != null && id != null; + return new UEntity(name, version, id, resolved); } /** - * Build an Software Entity that represents a communicating piece of software. - * @param name The name of the software such as petpp or body.access. - * @param version The software version. If not supplied, the latest version of the service will be used. + * Static factory method for creating a uE using the software entity name, that can be used to serialize long UUris. + * @param name The software entity name, such as petapp or body.access. + * @return Returns an UEntity with the name where the version is the latest version of the service and can only be serialized + * to long UUri format. */ - public UEntity(String name, Integer version) { - Objects.requireNonNull(name, " Software Entity must have a name"); - this.name = name; - this.id = null; - this.version = version; + public static UEntity longFormat(String name) { + return new UEntity(name, null, null, false); } /** - * Static factory method for creating a uE using the application or service name. - * @param name The application or service name, such as petapp or body.access. - * @return Returns an UEntity with the name where the version is the latest version of the service. + * Static factory method for creating a uE using the software entity name, that can be used to serialize long UUris. + * @param name The software entity name, such as petapp or body.access. + * @param version The software entity version. + * @return Returns an UEntity with the name and the version of the service and can only be serialized + * to long UUri format. */ - public static UEntity fromName(String name) { - return new UEntity(name, null); + public static UEntity longFormat(String name, Integer version) { + return new UEntity(name, version, null, false); } - /** - * Static factory method for creating a uE using id and version. - * @param version The software version. If not supplied, the latest version of the service will be used. - * @param id The software id. - * @return Returns a UEntity with id but unknown name. + * Static factory method for creating a uE using the software entity identification number, that can be used to serialize micro UUris. + * @param id The software entity name, such as petapp or body.access. + * @return Returns an UEntity with the name where the version is the latest version of the service and can only be serialized + * to long UUri format. */ - public static UEntity fromId(Integer version, Short id) { - Objects.requireNonNull(id, "ID must be supplied"); - return new UEntity(String.valueOf(id), version, id); + public static UEntity microFormat(Short id) { + return new UEntity("", null, id, false); } + /** + * Static factory method for creating a uE using the software entity identification number, that can be used to serialize micro UUris. + * @param id The software entity name, such as petapp or body.access. + * @param version The software entity version. + * @return Returns an UEntity with the name and the version of the service and can only be serialized + * to long UUri format. + */ + public static UEntity microFormat(Short id, Integer version) { + return new UEntity("", version, id, false); + } /** * Static factory method for creating an empty software entity, to avoid working with null
@@ -96,10 +113,37 @@ public static UEntity empty() { * Indicates that this USE is an empty container and has no valuable information in building uProtocol sinks or sources. * @return Returns true if this USE is an empty container and has no valuable information in building uProtocol sinks or sources. */ + @Override public boolean isEmpty() { - return name.isBlank() && version().isEmpty(); + return name.isBlank() && version().isEmpty() && id().isEmpty(); + } + + /** + * Return true if the UEntity contains both the name and IDs meaning it contains all the information to be serialized + * into a long UUri or a micro form UUri. + * @return Returns true of this resource contains resolved information meaning it contains all the information to be serialized + * into a long UUri or a micro form UUri. + */ + public boolean isResolved() { + return markedResolved; + } + + /** + * Determine if this software entity can be serialised into a long UUri form. + * @return Returns true if this software entity can be serialised into a long UUri form, meaning it has at least a name. + */ + public boolean isLongForm() { + return !name().isEmpty(); } + /** + * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. + * @return Returns true if the Uri part can be serialized into micro form. + */ + @Override + public boolean isMicroForm() { + return id().isPresent(); + } /** * @return Returns the name of the software such as petpp or body.access. @@ -117,8 +161,7 @@ public Optional version() { } /** - * @return Returns the software id if it exists. - * + * @return Returns the software id if it exists. The software id represents the numeric identifier of the uE. */ public Optional id() { return Optional.ofNullable(id); @@ -128,44 +171,24 @@ public Optional id() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - UEntity that = (UEntity) o; - return Objects.equals(name, that.name) && Objects.equals(version, that.version) && Objects.equals(id, that.id); + UEntity uEntity = (UEntity) o; + return markedResolved == uEntity.markedResolved && Objects.equals(name, uEntity.name) + && Objects.equals(version, uEntity.version) && Objects.equals(id, uEntity.id); } @Override public int hashCode() { - return Objects.hash(name, version, id); + return Objects.hash(name, version, id, markedResolved); } + @Override public String toString() { - return "UEntity{" + "name='" + name + '\'' - + ", version='" + (version == null ? "latest" : version) + '\'' + - ", id='" + (id == null ? "null" : id) + '\'' + '}'; - } - - - /** - * Return true if the UEntity contains both the name and IDs meaning it is resolved - * UEntity. Resolved UEntity contains name and id when the name and ID are not the same - * @return Returns true of this resource contains resolved information - */ - public boolean isResolved() { - boolean isResolved = !name.isBlank() && (id != null); - - try { - isResolved = (id != Short.valueOf(name)); - } catch (NumberFormatException e) { - return isResolved; - } - return isResolved; - } - - /** - * Check if the UEntity contains Long form URI information (uE name) - * @return Returns true if the UEntity contains Long form URI information (names) - */ - public boolean isLongForm() { - return isResolved() || !name.isBlank(); + return "UEntity{" + + "name='" + name + '\'' + + ", version=" + version + + ", id=" + id + + ", markedResolved=" + markedResolved + + '}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 4104e19e..85da95c1 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -31,13 +31,11 @@ * An UResource is something that can be manipulated/controlled/exposed by a service. Resources are unique when prepended with UAuthority that represents the device and * UEntity that represents the service. */ -public class UResource implements Uri { +public class UResource implements UriPart { - private static final UResource EMPTY = new UResource("", null,null, null); + private static final UResource EMPTY = new UResource("", null,null, null, false); - private static final UResource RESPONSE = new UResource("rpc", "response",null, Short.valueOf((short)0)); - - private static final String UNKNOWN_NAME = new String("unknown"); + private static final UResource RESPONSE = new UResource("rpc", "response",null, (short) 0, true); private final String name; @@ -47,124 +45,94 @@ public class UResource implements Uri { private final Short id; - /** - * Create an Resource. The resource is something that is manipulated by a service such as a door. - * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @param instance An instance of a resource such as front_left. - * @param message The Message type matches the protobuf service IDL message name that defines structured data types. - * A message is a data structure type used to define data that is passed in events and rpc methods. - */ - public UResource(String name, String instance, String message) { - this(name, instance, message, null); - } + private final boolean markedResolved; // Indicates that this UAuthority has already been resolved. /** - * Create an Resource. The resource is something that is manipulated by a service such as a door. + * Create a uResource. The resource is something that is manipulated by a service such as a door. * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. * @param instance An instance of a resource such as front_left. * @param message The Message type matches the protobuf service IDL message name that defines structured data types. * A message is a data structure type used to define data that is passed in events and rpc methods. + * @param id The numeric representation of this uResource. + * @param markedResolved Indicates that this uResource was populated with intent of having all data. */ - public UResource(String name, String instance, String message, Short id) { - Objects.requireNonNull(name, " Resource must have a name."); - this.name = name; + private UResource(String name, String instance, String message, Short id, boolean markedResolved) { + this.name = Objects.requireNonNullElse(name, ""); this.instance = instance; this.message = message; - if (name.equals("rpc") && instance != null && instance.equals("response")) { - this.id = Short.valueOf((short)0); - } else { - this.id = id; - } - + this.id = id; + this.markedResolved = markedResolved; } - /** - * Static factory method for creating an Resource using the resource id. - * @param id The id of the resource. - * @return Returns an UResource with the resource id where the name, instance and message are empty. + * Build a UResource that has serialization information. + * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. + * @param instance An instance of a resource such as front_left. + * @param message The Message type matches the protobuf service IDL message name that defines structured data types. + * A message is a data structure type used to define data that is passed in events and rpc methods. + * @param id The numeric representation of this uResource. + * @return Returns a UResource that has all the information that is needed to serialise into a long UUri or a micro UUri. */ - public static UResource fromId(Short id) { - Objects.requireNonNull(id, "id Required"); - if (id == 0) { - return RESPONSE; - } - return new UResource(UNKNOWN_NAME, null, null, id); + public static UResource resolved(String name, String instance, String message, Short id) { + boolean resolved = name != null && !name.isEmpty() && id != null; + return new UResource(name, instance, message, id, resolved); } /** - * Static factory method for creating an Resource using the resource name. + * Build a UResource that can be serialised into a long UUri. Mostly used for publishing messages. * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @return Returns an UResource with the resource name where the instance and message are empty. - * If the instance does not exist, it is assumed that all the instances of the resource are wanted. + * @return Returns a UResource that can be serialised into a long UUri. */ - public static UResource fromName(String name) { - return new UResource(name, null, null); + public static UResource longFormat(String name) { + return new UResource(name, null, null, null, false); } /** - * Static factory method for creating an Resource using the resource name and some resource instance. - * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @param instance An instance of a resource such as front_left. - * @return Returns an UResource with the resource name and a specific instance where the message is left empty. + * Build a UResource that can be serialised into a long UUri. Mostly used for publishing messages. + * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. + * @param instance An instance of a resource such as front_left. + * @param message The Message type matches the protobuf service IDL message name that defines structured data types. + * A message is a data structure type used to define data that is passed in events and rpc methods. + * @return Returns a UResource that can be serialised into a long UUri. */ - public static UResource fromNameWithInstance(String name, String instance) { - return new UResource(name, instance, null); + public static UResource longFormat(String name, String instance, String message) { + return new UResource(name, instance, message, null, false); } /** - * Static factory method for creating an Resource using a resource command name such as UpdateDoor. - * @param commandName The RPC command name such as UpdateDoor. - * @return returns an resource used for sending RPC commands. + * Build a UResource that can be serialised into a micro UUri. Mostly used for publishing messages. + * @param id The numeric representation of this uResource. + * @return Returns a UResource that can be serialised into a micro UUri. */ - public static UResource forRpc(String commandName) { - Objects.requireNonNull(commandName, " Resource must have a command name."); - return forRpc(commandName, null); + public static UResource microFormat(Short id) { + return new UResource("", null, null, id, false); } - /** - * Static factory method for creating an Resource using a resource command and ID. - * @param commandName The RPC command name such as UpdateDoor. - * @param id The RPC command id. - * @return returns an resource used for sending RPC commands. + * Build a UResource for rpc request, using only the long format. + * @param methodName The RPC method name. + * @return Returns a UResource used for an RPC request that could be serialised in long format. */ - public static UResource forRpc(String commandName, Short id) { - Objects.requireNonNull(commandName, " Resource must have a command name."); - return new UResource("rpc", commandName, null, id); + public static UResource forRpcRequest(String methodName) { + return new UResource("rpc", methodName, null, null, false); } /** - * Static factory method for creating a UResource using a string that contains either the id or - * a name + instance + message. - * @param resourceString String that contains the UResource information. - * @return Returns a UResource object + * Build a UResource for rpc request, using only the micro format. + * @param methodId The numeric representation method name for the RPC. + * @return Returns a UResource used for an RPC request that could be serialised in micro format. */ - public static UResource parseFromString(String resourceString) { - Objects.requireNonNull(resourceString, " Resource must have a command name."); - String[] parts = resourceString.split("#"); - String nameAndInstance = parts[0]; - - // Try and fetch the resource ID if there is one (short form) - Short maybeId = null; - try { - maybeId = Short.parseShort(nameAndInstance); - } catch (NumberFormatException e) { - maybeId = null; - - } - - if (maybeId != null) { - return UResource.fromId(maybeId); - } - - String[] nameAndInstanceParts = nameAndInstance.split("\\."); - String resourceName = nameAndInstanceParts[0]; - String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; - String resourceMessage = parts.length > 1 ? parts[1] : null; - return new UResource(resourceName, resourceInstance, resourceMessage); + public static UResource forRpcRequest(Short methodId) { + return new UResource("rpc", null, null, methodId, false); } + /** + * Static factory method for creating a response resource that is returned from RPC calls
+ * @return Returns a response resource used for response RPC calls. + */ + public static UResource forRpcResponse() { + return RESPONSE; + } /** * @return Returns true if this resource specifies an RPC method call. @@ -181,20 +149,12 @@ public static UResource empty() { return EMPTY; } - /** - * Static factory method for creating a response resource that is returned from RPC calls
- * @return Returns a response resource used for response RPC calls. - */ - public static UResource response() { - return RESPONSE; - } - /** * Indicates that this resource is an empty container and has no valuable information in building uProtocol URI. * @return Returns true if this resource is an empty container and has no valuable information in building uProtocol URI. */ public boolean isEmpty() { - return name.isBlank() && instance().isEmpty() && message().isEmpty(); + return name.isBlank() && instance().isEmpty() && message().isEmpty() && id().isEmpty(); } /** @@ -211,16 +171,6 @@ public Optional id() { return Optional.ofNullable(id); } - /** - * Support for building the name attribute in many protobuf Message objects. - * Will build a string with the name and instance with a dot delimiter, only if the instance exists. - * @return Returns a string used for building the name attribute in many protobuf Message objects. - * Will build a string with the name and instance with a dot delimiter, only if the instance exists. - */ - public String nameWithInstance() { - return instance().isPresent() ? String.format("%s.%s", name(), instance().get()) : name(); - } - /** * An instance of a resource such as front_left * or in the case of RPC a method name that manipulates the resource such as UpdateDoor. @@ -231,7 +181,6 @@ public Optional instance() { return instance == null || instance.isBlank() ? Optional.empty() : Optional.of(instance); } - /** * The Message type matches the protobuf service IDL that defines structured data types. * A message is a data structure type used to define data that is passed in events and rpc methods. @@ -241,18 +190,47 @@ public Optional message() { return message == null || message.isBlank() ? Optional.empty() : Optional.of(message); } + /** + * Return true if this resource contains both ID and names. + * Method type of UResource requires name, instance, and ID where a topic + * type of UResource also requires message to not be null + * @return Returns true of this resource contains resolved information + */ + public boolean isResolved() { + return markedResolved; + } + + /** + * Returns true if the uResource contains names so that it can be serialized to long format. + * @return Returns true if the uResource contains names so that it can be serialized to long format. + */ + @Override + public boolean isLongForm() { + return !name().isEmpty() && instance().isPresent(); + } + + /** + * Returns true if the uResource contains the id's which will allow the Uri part to be serialized into micro form. + * @return Returns true if the uResource can be serialized into micro form. + */ + @Override + public boolean isMicroForm() { + return id().isPresent(); + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - UResource that = (UResource) o; - return Objects.equals(name, that.name) && Objects.equals(instance, that.instance) && - Objects.equals(message, that.message) && Objects.equals(id, that.id); + UResource uResource = (UResource) o; + return markedResolved == uResource.markedResolved && Objects.equals(name, uResource.name) + && Objects.equals(instance, uResource.instance) && Objects.equals(message, uResource.message) + && Objects.equals(id, uResource.id); } @Override public int hashCode() { - return Objects.hash(name, instance, message, id); + return Objects.hash(name, instance, message, id, markedResolved); } @Override @@ -261,21 +239,8 @@ public String toString() { "name='" + name + '\'' + ", instance='" + instance + '\'' + ", message='" + message + '\'' + - ", id='" + (id == null ? "null" : id) + '\'' + + ", id=" + id + + ", markedResolved=" + markedResolved + '}'; } - - /** - * Return true if this resource contains both ID and names. - * Method type of UResource requires name, instance, and ID where a topic - * type of UResource also requires message to not be null - * @return Returns true of this resource contains resolved information - */ - public boolean isResolved() { - return (id != null) && isLongForm(); - } - - public boolean isLongForm() { - return !name.equals(UNKNOWN_NAME) && (instance != null) && (isRPCMethod() || (message != null)); - } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 193af0ab..d6b2df70 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -24,30 +24,30 @@ import java.util.Objects; /** - * Data representation of an URI. - * This class will be used to represent the source and sink (destination) parts of the Packet CloudEvent.
- * URI is used as a method to uniquely identify devices, services, and resources on the network.
+ * Data representation of uProtocol URI. + * This class will be used to represent the source and sink (destination) parts of the Packet, for example in a CloudEvent Packet.
+ * UUri is used as a method to uniquely identify devices, services, and resources on the network.
+ * Where software is deployed, what the service is called along with a version and the resources in the service. * Defining a common URI for the system allows applications and/or services to publish and discover each other * as well as maintain a database/repository of microservices in the various vehicles.
- * Example: + * Example for long format serialisation: *
  *     //<device>.<domain>/<service>/<version>/<resource>#<message>
  * 
* */ -public class UUri implements Uri { +public class UUri { private static final UUri EMPTY = new UUri(UAuthority.empty(), UEntity.empty(), UResource.empty()); private final UAuthority uAuthority; private final UEntity uEntity; private final UResource uResource; - /** * Create a full URI. - * @param uAuthority The Authority represents the deployment location of a specific Software Entity . - * @param uEntity The USE in the role of a service or in the role of an application. - * @param uResource The resource is something that is manipulated by a service such as a Door. + * @param uAuthority The uAuthority represents the deployment location of a specific Software Entity . + * @param uEntity The uEntity in the role of a service or in the role of an application is the software and version. + * @param uResource The uResource is something that is manipulated by a service such as a Door. */ public UUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { this.uAuthority = Objects.requireNonNullElse(uAuthority, UAuthority.empty()); @@ -56,24 +56,24 @@ public UUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { } /** - * Create an URI for a resource. This will match all the specific instances of the resource, + * Create a URI for a resource. This will match all the specific instances of the resource, * for example all the instances of the vehicle doors. * @param uAuthority The Authority represents the deployment location of a specific Software Entity. * @param uEntity The USE in the role of a service or in the role of an application. * @param uResource The resource is something that is manipulated by a service such as a Door. */ public UUri(UAuthority uAuthority, UEntity uEntity, String uResource) { - this(uAuthority, uEntity, UResource.fromName(uResource)); + this(uAuthority, uEntity, UResource.longFormat(uResource)); } /** - * Create a RPC Response UUri passing the Authority and Entity information - * @param uAuthority The Authority represents the deployment location of a specific Software Entity. - * @param uEntity The SW entity information - * @return Returns a UUri of a constructed RPC Response + * Create an RPC Response UUri passing the Authority and Entity information. + * @param uAuthority The uAuthority represents the deployment location of a specific Software Entity. + * @param uEntity The SW entity information. + * @return Returns a UUri of a constructed RPC Response. */ public static UUri rpcResponse(UAuthority uAuthority, UEntity uEntity) { - return new UUri(uAuthority, uEntity, UResource.response()); + return new UUri(uAuthority, uEntity, UResource.forRpcResponse()); } @@ -94,6 +94,32 @@ public boolean isEmpty() { && uResource.isEmpty(); } + /** + * Returns true if URI contains both names and numeric representations of the names inside its belly. + * Meaning that this UUri can be serialised to long or micro formats. + * @return Returns true if URI contains both names and numeric representations of the names inside its belly. + * Meaning that this UUri can be serialised to long or micro formats. + */ + public boolean isResolved() { + return uAuthority.isResolved() && uEntity.isResolved() && uResource.isResolved(); + } + + /** + * Determines if this UUri can be serialised into a long form UUri. + * @return Returns true if this UUri can be serialised into a long form UUri. + */ + public boolean isLongForm() { + return uAuthority.isLongForm() && uEntity.isLongForm() && uResource.isLongForm(); + } + + /** + * Determines if this UUri can be serialised into a micro form UUri. + * @return Returns true if this UUri can be serialised into a micro form UUri. + */ + public boolean isMicroForm() { + return uAuthority.isMicroForm() && uEntity.isMicroForm() && uResource.isMicroForm(); + } + /** * @return Returns the Authority represents the deployment location of a specific Software Entity. */ @@ -131,27 +157,10 @@ public int hashCode() { @Override public String toString() { - return "Uri{" + + return "UriPart{" + "uAuthority=" + uAuthority + ", uEntity=" + uEntity + ", uResource=" + uResource + '}'; } - - /** - * Returns true if URI contains both names and numeric representations of the names inside - * its belly. - * @return Returns true if URI contains both names and numeric representations of the names inside - */ - public boolean isResolved() { - return uAuthority.isResolved() && uEntity.isResolved() && uResource.isResolved(); - } - - /** - * Check if the UEntity and UResource contains Long form URI information (names) - * @return Returns true if the UEntity and UResource contains Long form URI information (names) - */ - public boolean isLongForm() { - return isResolved() || uEntity.isLongForm() && uResource.isLongForm(); - } } \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java deleted file mode 100644 index 45f9ec05..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/Uri.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.eclipse.uprotocol.uri.datamodel; - -/** - * Basic building blocks for all objects that are art of a uProtocol URI. The - * interface defines APIs that MUST be implemented in all objects. - */ -public interface Uri { - - /** - * Return true if the object is empty - * @return true if the object is empty - */ - public boolean isEmpty(); - - - /** - * Check if the passed object is equal to this object - * @param o The object to compare - * @return true if the passed object is equal to this object - */ - public boolean equals(Object o); - - /** - * Return the hash code of this object - * @return the hash code of this object - */ - public int hashCode(); - - /** - * Return the string representation of this object - * @return the string representation of this object - */ - public String toString(); - - /** - * Returns true if the object contains both names and ids (numbers) corresponding to the - * data inside of its belly. Return of true means that the object can be serialized to both - * long and micro uri format. - * @return Returns true if the object contains both names and ids (numbers) - */ - public boolean isResolved(); - - /** - * Returns true if the object contains names so that it can be serialized to long format. - * @return Returns true if the object contains names so that it can be serialized to long format. - */ - public boolean isLongForm(); -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java new file mode 100644 index 00000000..bea3d222 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java @@ -0,0 +1,33 @@ +package org.eclipse.uprotocol.uri.datamodel; + +/** + * Basic building blocks for all data models that are part of a uProtocol URI. + * The interface defines APIs that MUST be implemented in all Uri uProtocol parts. + */ +public interface UriPart { + + /** + * Supporting empty Uri parts enables avoiding null values in the data model, and can indicate the absence of a Uri Part. + * @return Returns true if the Uri part is empty. + */ + boolean isEmpty(); + + /** + * Returns true if the Uri part contains both names and ids (numbers) corresponding to the data inside its belly. + * isResolved true means that the Uri part can be serialized to both long and micro uri format. + * @return Returns true if the Uri part contains both names and ids (numbers), long and micro representations. + */ + boolean isResolved(); + + /** + * Returns true if the Uri part contains names so that it can be serialized to long format. + * @return Returns true if the Uri part contains names so that it can be serialized to long format. + */ + boolean isLongForm(); + + /** + * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. + * @return Returns true if the Uri part can be serialized into micro form. + */ + boolean isMicroForm(); +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index e347191b..049783f7 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -25,7 +25,9 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; + import java.util.Arrays; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -135,7 +137,7 @@ public UUri deserialize(String uProtocolUri) { if(numberOfPartsInUri == 0 || numberOfPartsInUri == 1) { return isLocal ? UUri.empty() : - new UUri(UAuthority.remote("", ""), UEntity.empty(), UResource.empty()); + new UUri(UAuthority.longRemote("", ""), UEntity.empty(), UResource.empty()); } String useName; @@ -164,7 +166,7 @@ public UUri deserialize(String uProtocolUri) { .skip(1) .collect(Collectors.joining(".")); } - uAuthority = UAuthority.remote(device, domain); + uAuthority = UAuthority.longRemote(device, domain); if (uriParts.length > 3) { useName = uriParts[3]; @@ -194,4 +196,35 @@ public UUri deserialize(String uProtocolUri) { return new UUri(uAuthority, new UEntity(useName, useVersionInt), uResource); } + /** + * Static factory method for creating a UResource using a string that contains either the id or + * a name + instance + message. + * @param resourceString String that contains the UResource information. + * @return Returns a UResource object + */ + private static UResource parseFromString(String resourceString) { + Objects.requireNonNull(resourceString, " Resource must have a command name."); + String[] parts = resourceString.split("#"); + String nameAndInstance = parts[0]; + + // Try and fetch the resource ID if there is one (short form) + Short maybeId = null; + try { + maybeId = Short.parseShort(nameAndInstance); + } catch (NumberFormatException e) { + maybeId = null; + + } + + if (maybeId != null) { + return UResource.fromId(maybeId); + } + + String[] nameAndInstanceParts = nameAndInstance.split("\\."); + String resourceName = nameAndInstanceParts[0]; + String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; + String resourceMessage = parts.length > 1 ? parts[1] : null; + return new UResource(resourceName, resourceInstance, resourceMessage); + } + } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index c8879ea3..aa93f203 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -43,7 +43,7 @@ public class MicroUriSerializer implements UriSerializer { static final int IPV4_MICRO_URI_LENGTH = 12; // IPv4 micro URI length - static final int IPV6_MICRO_URI_LENGTH = 24; // IPv6 micro Uri length + static final int IPV6_MICRO_URI_LENGTH = 24; // IPv6 micro UriPart length static final byte UP_VERSION = 0x1; // UP version @@ -189,7 +189,7 @@ else if (type.get() == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LEN // UE_VERSION int uiVersion = microUri[index++]; - return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.remote(maybeAddress.get()), + return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.microRemote(maybeAddress.get()), UEntity.fromId(uiVersion, (short)ueId), UResource.fromId((short)uResourceId)); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 963ff5ea..63fe8d41 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -13,24 +13,24 @@ public interface UriValidator { /** - * Validate a Uri to ensure that it has at least a name for the uEntity. - * @param uri Uri to validate. + * Validate a UriPart to ensure that it has at least a name for the uEntity. + * @param uri UriPart to validate. * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validate(UUri uri) { if (uri.isEmpty()) { - return UStatus.failed("Uri is empty.", Code.INVALID_ARGUMENT); + return UStatus.failed("UriPart is empty.", Code.INVALID_ARGUMENT); } if (uri.uEntity().name().isBlank()) { - return UStatus.failed("Uri is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); + return UStatus.failed("UriPart is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); } return UStatus.ok(); } /** - * Validate a Uri that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. - * @param uri Uri to validate. + * Validate a UriPart that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. + * @param uri UriPart to validate. * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validateRpcMethod(UUri uri) { @@ -40,15 +40,15 @@ public static UStatus validateRpcMethod(UUri uri) { } final UResource uResource = uri.uResource(); if (!uResource.isRPCMethod()) { - return UStatus.failed("Invalid RPC method uri. Uri should be the method to be called, or method from response.", Code.INVALID_ARGUMENT); + return UStatus.failed("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", Code.INVALID_ARGUMENT); } return UStatus.ok(); } /** - * Validate a Uri that is meant to be used as an RPC response URI. Used in Request source values and Response sink values. + * Validate a UriPart that is meant to be used as an RPC response URI. Used in Request source values and Response sink values. * - * @param uri Uri to validate. + * @param uri UriPart to validate. * @return Returns UStatus containing a success or a failure with the error message. */ public static UStatus validateRpcResponse(UUri uri) { diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 307f86f3..4c01ae99 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -70,7 +70,7 @@ public class UAttributes { * @param reqid Request ID, used to indicate the id of the RPC request that matches this RPC response. */ private UAttributes(UUID id, UMessageType type, UPriority priority, Integer ttl, String token, - UUri sink, Integer plevel, Integer commstatus, UUID reqid) { + UUri sink, Integer plevel, Integer commstatus, UUID reqid) { this.id = id; this.type = type; this.priority = priority; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java index 4e8f7cca..31fa43fe 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java @@ -168,7 +168,7 @@ public UStatus validateTtl(UAttributes attributes) { } /** - * Validate the sink Uri for the default case. If the UAttributes does not contain a sink then the UStatus is ok. + * Validate the sink UriPart for the default case. If the UAttributes does not contain a sink then the UStatus is ok. * @param attributes UAttributes object containing the sink to validate. * @return Returns a {@link UStatus} that is success or failed with a failure message. */ diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index 322b95ee..58ed137c 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -218,7 +218,7 @@ public void test_create_notification_cloud_event() { // sink UEntity sinkUse = UEntity.fromName("petapp"); - UUri sinkUri = new UUri(UAuthority.remote("com.gm.bo", "bo"), sinkUse, "OK"); + UUri sinkUri = new UUri(UAuthority.longRemote("com.gm.bo", "bo"), sinkUse, "OK"); String sink = UriSerializer.LONG.serialize(sinkUri); // fake payload @@ -254,11 +254,11 @@ public void test_create_notification_cloud_event() { @DisplayName("Test create request RPC CloudEvent coming from a local USE") public void test_create_request_cloud_event_from_local_use() { - // Uri for the application requesting the RPC + // UriPart for the application requesting the RPC UEntity sourceUse = UEntity.fromName("petapp"); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); - // service Method Uri + // service Method UriPart UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); @@ -296,17 +296,17 @@ public void test_create_request_cloud_event_from_local_use() { } @Test - @DisplayName("Test create request RPC CloudEvent coming from a remote USE") + @DisplayName("Test create request RPC CloudEvent coming from a microRemote USE") public void test_create_request_cloud_event_from_remote_use() { - // Uri for the application requesting the RPC - UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); + // UriPart for the application requesting the RPC + UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); UEntity sourceUse = new UEntity("petapp", 1); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); - // service Method Uri + // service Method UriPart UEntity methodSoftwareEntityService = new UEntity("body.access", 1); - UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), + UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); @@ -346,11 +346,11 @@ public void test_create_request_cloud_event_from_remote_use() { @DisplayName("Test create response RPC CloudEvent originating from a local USE") public void test_create_response_cloud_event_originating_from_local_use() { - // Uri for the application requesting the RPC + // UriPart for the application requesting the RPC UEntity sourceUse = new UEntity("petapp", 1); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); - // service Method Uri + // service Method UriPart UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); @@ -388,18 +388,18 @@ public void test_create_response_cloud_event_originating_from_local_use() { } @Test - @DisplayName("Test create response RPC CloudEvent originating from a remote USE") + @DisplayName("Test create response RPC CloudEvent originating from a microRemote USE") public void test_create_response_cloud_event_originating_from_remote_use() { - // Uri for the application requesting the RPC - UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); + // UriPart for the application requesting the RPC + UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); UEntity sourceUse = UEntity.fromName("petapp"); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); - // service Method Uri + // service Method UriPart UEntity methodSoftwareEntityService = new UEntity("body.access", 1); - UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), + UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); @@ -440,11 +440,11 @@ public void test_create_response_cloud_event_originating_from_remote_use() { @DisplayName("Test create a failed response RPC CloudEvent originating from a local USE") public void test_create_a_failed_response_cloud_event_originating_from_local_use() { - // Uri for the application requesting the RPC + // UriPart for the application requesting the RPC UEntity sourceUse = new UEntity("petapp", 1); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); - // service Method Uri + // service Method UriPart UEntity methodSoftwareEntityService = new UEntity("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); @@ -480,18 +480,18 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use } @Test - @DisplayName("Test create a failed response RPC CloudEvent originating from a remote USE") + @DisplayName("Test create a failed response RPC CloudEvent originating from a microRemote USE") public void test_create_a_failed_response_cloud_event_originating_from_remote_use() { - // Uri for the application requesting the RPC - UAuthority sourceUseAuthority = UAuthority.remote("bo", "cloud"); + // UriPart for the application requesting the RPC + UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); UEntity sourceUse = UEntity.fromName("petapp"); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); - // service Method Uri + // service Method UriPart UEntity methodSoftwareEntityService = new UEntity("body.access", 1); - UUri methodUri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), + UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpc("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index db5f7fcd..ca3cfa88 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -223,7 +223,7 @@ void validate_cloud_event_id_when_not_valid() { } @Test - @DisplayName("Test validate software entity uri with version, when it is valid remote") + @DisplayName("Test validate software entity uri with version, when it is valid microRemote") void test_usoftware_entity_uri_with_version_when_it_is_valid_remote() { final String uri = "//VCU.MY_CAR_VIN/body.access/1"; @@ -233,7 +233,7 @@ void test_usoftware_entity_uri_with_version_when_it_is_valid_remote() { } @Test - @DisplayName("Test validate software entity uri no version, when it is valid remote") + @DisplayName("Test validate software entity uri no version, when it is valid microRemote") void test_usoftware_entity_uri_no_version_when_it_is_valid_remote() { final String uri = "//VCU.MY_CAR_VIN/body.access"; @@ -270,29 +270,29 @@ void test_usoftware_entity_uri_invalid_when_uri_has_schema_only() { final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test - @DisplayName("Test validate software entity uri is invalid when uri is remote but missing authority") + @DisplayName("Test validate software entity uri is invalid when uri is microRemote but missing authority") void test_usoftware_entity_uri_invalid_when_uri_is_remote_no_authority() { final String uri = "//"; final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test - @DisplayName("Test validate software entity uri is invalid when uri is remote with use but missing authority") + @DisplayName("Test validate software entity uri is invalid when uri is microRemote with use but missing authority") void test_usoftware_entity_uri_invalid_when_uri_is_remote_no_authority_with_use() { final String uri = "///body.access/1"; final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test @@ -303,7 +303,7 @@ void test_usoftware_entity_uri_invalid_when_uri_is_missing_use() { final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -314,11 +314,11 @@ void test_usoftware_entity_uri_invalid_when_uri_is_missing_use_name_local() { final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test - @DisplayName("Test validate topic uri with version, when it is valid remote") + @DisplayName("Test validate topic uri with version, when it is valid microRemote") void test_topic_uri_with_version_when_it_is_valid_remote() { final String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; @@ -328,7 +328,7 @@ void test_topic_uri_with_version_when_it_is_valid_remote() { } @Test - @DisplayName("Test validate topic uri no version, when it is valid remote") + @DisplayName("Test validate topic uri no version, when it is valid microRemote") void test_topic_uri_no_version_when_it_is_valid_remote() { final String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; @@ -365,7 +365,7 @@ void test_topic_uri_invalid_when_uri_has_schema_only() { final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -376,29 +376,29 @@ void test_topic_uri_invalid_when_uri_has_empty_use_name_local() { final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test - @DisplayName("Test validate topic uri is invalid when uri is remote but missing authority") + @DisplayName("Test validate topic uri is invalid when uri is microRemote but missing authority") void test_topic_uri_invalid_when_uri_is_remote_no_authority() { final String uri = "//"; final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test - @DisplayName("Test validate topic uri is invalid when uri is remote with use but missing authority") + @DisplayName("Test validate topic uri is invalid when uri is microRemote with use but missing authority") void test_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() { final String uri = "///body.access/1/door.front_left#Door"; final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test @@ -409,18 +409,18 @@ void test_topic_uri_invalid_when_uri_is_missing_use_remote() { final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test - @DisplayName("Test validate remote topic uri is invalid when uri is missing use name") + @DisplayName("Test validate microRemote topic uri is invalid when uri is missing use name") void test_topic_uri_invalid_when_uri_is_missing_use_name_remote() { final String uri = "/1/door.front_left#Door"; final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uResource name.", status.getMessage()); + assertEquals("UriPart is missing uResource name.", status.getMessage()); } @Test @@ -431,44 +431,44 @@ void test_topic_uri_invalid_when_uri_is_missing_use_name_local() { final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test - @DisplayName("Test validate remote topic uri, when uri has authority and use no version missing resource") + @DisplayName("Test validate microRemote topic uri, when uri has authority and use no version missing resource") void test_topic_uri_when_uri_is_with_authority_with_use_no_version_missing_resource_remote() { final String source = "//VCU.myvin/body.access"; final Status status = CloudEventValidator.validateTopicUri(source).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uResource name.", status.getMessage()); + assertEquals("UriPart is missing uResource name.", status.getMessage()); } @Test - @DisplayName("Test validate remote topic uri, when uri has authority and use with version missing resource") + @DisplayName("Test validate microRemote topic uri, when uri has authority and use with version missing resource") void test_topic_uri_when_uri_is_with_authority_with_use_with_version_missing_resource_remote() { final String source = "//VCU.myvin/body.access/"; final Status status = CloudEventValidator.validateTopicUri(source).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing uResource name.", status.getMessage()); + assertEquals("UriPart is missing uResource name.", status.getMessage()); } @Test - @DisplayName("Test validate remote topic uri, when uri has authority and use and resource missing Message") + @DisplayName("Test validate microRemote topic uri, when uri has authority and use and resource missing Message") void test_topic_uri_when_uri_is_with_authority_with_use_with_resource_missing_message_remote() { final String source = "//VCU.myvin/body.access/1/door.front_left"; final Status status = CloudEventValidator.validateTopicUri(source).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Uri is missing Message information.", status.getMessage()); + assertEquals("UriPart is missing Message information.", status.getMessage()); } @Test - @DisplayName("Test validate rpc topic uri with version, when it is valid remote") + @DisplayName("Test validate rpc topic uri with version, when it is valid microRemote") void test_rpc_topic_uri_with_version_when_it_is_valid_remote() { final String uri = "//bo.cloud/petapp/1/rpc.response"; @@ -478,7 +478,7 @@ void test_rpc_topic_uri_with_version_when_it_is_valid_remote() { } @Test - @DisplayName("Test validate rpc topic uri no version, when it is valid remote") + @DisplayName("Test validate rpc topic uri no version, when it is valid microRemote") void test_rpc_topic_uri_no_version_when_it_is_valid_remote() { final String uri = "//bo.cloud/petapp//rpc.response"; @@ -515,7 +515,7 @@ void test_rpc_topic_uri_invalid_when_uri_has_schema_only() { final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -526,40 +526,40 @@ void test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_l final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing rpc.response.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); } @Test - @DisplayName("Test validate rpc topic uri with version, when it is remote but missing rpc.respons") + @DisplayName("Test validate rpc topic uri with version, when it is microRemote but missing rpc.respons") void test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_remote() { final String uri = "//petapp/1/dog"; final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing rpc.response.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); } @Test - @DisplayName("Test validate rpc topic uri is invalid when uri is remote but missing authority") + @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote but missing authority") void test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority() { final String uri = "//"; final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test - @DisplayName("Test validate rpc topic uri is invalid when uri is remote with use but missing authority") + @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote with use but missing authority") void test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() { final String uri = "///body.access/1"; final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test @@ -570,18 +570,18 @@ void test_rpc_topic_uri_invalid_when_uri_is_missing_use() { final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test - @DisplayName("Test validate remote rpc topic uri is invalid when uri is missing use name") + @DisplayName("Test validate microRemote rpc topic uri is invalid when uri is missing use name") void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_remote() { final String uri = "/1"; final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing rpc.response.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); } @Test @@ -592,7 +592,7 @@ void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() { final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -600,7 +600,7 @@ void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() { void test_rpc_topic__uri_with_version_when_it_is_valid() { UEntity use = new UEntity("petapp", 1); - UAuthority uAuthority = UAuthority.remote("bo", "cloud"); + UAuthority uAuthority = UAuthority.longRemote("bo", "cloud"); UResource uResource = UResource.fromNameWithInstance("rpc", "response"); UUri Uri = new UUri(uAuthority, use, uResource); @@ -613,17 +613,17 @@ void test_rpc_topic__uri_with_version_when_it_is_valid() { void test_rpc_topic__uri_with_version_when_it_is_not_valid() { UEntity use = new UEntity("petapp", 1); - UAuthority uAuthority = UAuthority.remote("bo", "cloud"); + UAuthority uAuthority = UAuthority.longRemote("bo", "cloud"); UResource uResource = UResource.fromNameWithInstance("body.access", "front_left"); UUri Uri = new UUri(uAuthority, use, uResource); final Status status = CloudEventValidator.validateRpcTopicUri(Uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. Uri is missing rpc.response.", status.getMessage()); + assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); } @Test - @DisplayName("Test validate rpc method uri with version, when it is valid remote") + @DisplayName("Test validate rpc method uri with version, when it is valid microRemote") void test_rpc_method_uri_with_version_when_it_is_valid_remote() { final String uri = "//VCU.myvin/body.access/1/rpc.UpdateDoor"; @@ -633,7 +633,7 @@ void test_rpc_method_uri_with_version_when_it_is_valid_remote() { } @Test - @DisplayName("Test validate rpc method uri no version, when it is valid remote") + @DisplayName("Test validate rpc method uri no version, when it is valid microRemote") void test_rpc_method_uri_no_version_when_it_is_valid_remote() { final String uri = "//VCU.myvin/body.access//rpc.UpdateDoor"; @@ -670,7 +670,7 @@ void test_rpc_method_uri_invalid_when_uri_has_schema_only() { final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -681,40 +681,40 @@ void test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_local( final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); } @Test - @DisplayName("Test validate rpc method uri with version, when it is remote but not an rpc method") + @DisplayName("Test validate rpc method uri with version, when it is microRemote but not an rpc method") void test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_remote() { final String uri = "//body.access/1/UpdateDoor"; final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); } @Test - @DisplayName("Test validate rpc method uri is invalid when uri is remote but missing authority") + @DisplayName("Test validate rpc method uri is invalid when uri is microRemote but missing authority") void test_rpc_method_uri_invalid_when_uri_is_remote_no_authority() { final String uri = "//"; final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test - @DisplayName("Test validate rpc method uri is invalid when uri is remote with use but missing authority") + @DisplayName("Test validate rpc method uri is invalid when uri is microRemote with use but missing authority") void test_rpc_method_uri_invalid_when_uri_is_remote_no_authority_with_use() { final String uri = "///body.access/1/rpc.UpdateDoor"; final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri is configured to be remote and is missing uAuthority device name.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); } @Test @@ -725,7 +725,7 @@ void test_rpc_method_uri_invalid_when_uri_is_missing_use() { final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -736,18 +736,18 @@ void test_rpc_method_uri_invalid_when_uri_is_missing_use_name_local() { final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); } @Test - @DisplayName("Test validate remote rpc method uri is invalid when uri is missing use name") + @DisplayName("Test validate microRemote rpc method uri is invalid when uri is missing use name") void test_rpc_method_uri_invalid_when_uri_is_missing_use_name_remote() { final String uri = "//VCU.myvin//1/rpc.UpdateDoor"; final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid RPC method uri. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -765,7 +765,7 @@ void test_publish_type_cloudevent_is_valid_when_everything_is_valid_local() { } @Test - @DisplayName("Test remote Publish type CloudEvent is valid everything is valid") + @DisplayName("Test microRemote Publish type CloudEvent is valid everything is valid") void test_publish_type_cloudevent_is_valid_when_everything_is_valid_remote() { UUID uuid = UUIDFactory.Factories.UPROTOCOL.factory().create(); CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() @@ -779,7 +779,7 @@ void test_publish_type_cloudevent_is_valid_when_everything_is_valid_remote() { } @Test - @DisplayName("Test remote Publish type CloudEvent is valid everything is valid with a sink") + @DisplayName("Test microRemote Publish type CloudEvent is valid everything is valid with a sink") void test_publish_type_cloudevent_is_valid_when_everything_is_valid_remote_with_a_sink() { UUID uuid = UUIDFactory.Factories.UPROTOCOL.factory().create(); CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() @@ -794,7 +794,7 @@ void test_publish_type_cloudevent_is_valid_when_everything_is_valid_remote_with_ } @Test - @DisplayName("Test remote Publish type CloudEvent is not valid everything is valid with invalid sink") + @DisplayName("Test microRemote Publish type CloudEvent is not valid everything is valid with invalid sink") void test_publish_type_cloudevent_is_not_valid_when_remote_with_invalid_sink() { UUID uuid = UUIDFactory.Factories.UPROTOCOL.factory().create(); CloudEventBuilder builder = buildBaseCloudEventBuilderForTest() @@ -806,7 +806,7 @@ void test_publish_type_cloudevent_is_not_valid_when_remote_with_invalid_sink() { final CloudEventValidator validator = CloudEventValidator.Validators.PUBLISH.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid CloudEvent sink [//bo.cloud]. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -821,7 +821,7 @@ void test_publish_type_cloudevent_is_not_valid_when_source_is_empty() { final CloudEventValidator validator = CloudEventValidator.Validators.PUBLISH.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid Publish type CloudEvent source [/]. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid Publish type CloudEvent source [/]. UriPart is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -836,7 +836,7 @@ void test_publish_type_cloudevent_is_not_valid_when_source_is_missing_authority( final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); assertEquals("Invalid CloudEvent Id [testme]. CloudEvent Id must be of type UUIDv8.," + - "Invalid Publish type CloudEvent source [/body.access]. Uri is missing uResource name.", status.getMessage()); + "Invalid Publish type CloudEvent source [/body.access]. UriPart is missing uResource name.", status.getMessage()); } @Test @@ -882,7 +882,7 @@ void test_notification_type_cloudevent_is_not_valid_invalid_sink() { final CloudEventValidator validator = CloudEventValidator.Validators.NOTIFICATION.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid Notification type CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid Notification type CloudEvent sink [//bo.cloud]. UriPart is missing uSoftware Entity name.", status.getMessage()); } @@ -915,7 +915,7 @@ void test_request_type_cloudevent_is_not_valid_invalid_source() { final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); assertEquals("Invalid RPC Request CloudEvent source [//bo.cloud/petapp//dog]. " + - "Invalid RPC uri application response topic. Uri is missing rpc.response.", status.getMessage()); + "Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); } @Test @@ -947,7 +947,7 @@ void test_request_type_cloudevent_is_not_valid_invalid_sink_not_rpc_command() { final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); assertEquals("Invalid RPC Request CloudEvent sink [//VCU.myvin/body.access/1/UpdateDoor]. " + - "Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.getMessage()); + "Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); } @Test @@ -979,7 +979,7 @@ void test_response_type_cloudevent_is_not_valid_invalid_source() { final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); assertEquals("Invalid RPC Response CloudEvent source [//VCU.myvin/body.access/1/UpdateDoor]. " + - "Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.getMessage()); + "Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); } @Test @@ -995,7 +995,7 @@ void test_response_type_cloudevent_is_not_valid_missing_sink_and_invalid_source( final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); assertEquals("Invalid RPC Response CloudEvent source [//VCU.myvin/body.access/1/UpdateDoor]. " + - "Invalid RPC method uri. Uri should be the method to be called, or method from response.," + + "Invalid RPC method uri. UriPart should be the method to be called, or method from response.," + "Invalid CloudEvent sink. Response CloudEvent sink must be uri the destination of the response.", status.getMessage()); } @@ -1012,9 +1012,9 @@ void test_response_type_cloudevent_is_not_valid_invalid_source_not_rpc_command() final CloudEventValidator validator = CloudEventValidator.Validators.RESPONSE.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC Response CloudEvent source [//bo.cloud/petapp/1/dog]. Invalid RPC method uri. Uri should be the method to be called, or method from response.," + + assertEquals("Invalid RPC Response CloudEvent source [//bo.cloud/petapp/1/dog]. Invalid RPC method uri. UriPart should be the method to be called, or method from response.," + "Invalid RPC Response CloudEvent sink [//VCU.myvin/body.access/1/UpdateDoor]. " + - "Invalid RPC uri application response topic. Uri is missing rpc.response.", status.getMessage()); + "Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); } private CloudEventBuilder buildBaseCloudEventBuilderForTest() { diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index 925b818f..d7efd780 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -42,7 +42,7 @@ public void testHashCodeEquals() { @Test @DisplayName("Make sure the toString works") public void testToString() { - UAuthority uAuthority = UAuthority.remote("VCU", "my_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "my_VIN"); String sRemote = uAuthority.toString(); String expectedRemote = "UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}"; assertEquals(expectedRemote, sRemote); @@ -57,7 +57,7 @@ public void testToString() { @Test @DisplayName("Make sure the toString works with case sensitivity") public void testToString_case_sensitivity() { - UAuthority uAuthority = UAuthority.remote("vcU", "my_VIN"); + UAuthority uAuthority = UAuthority.longRemote("vcU", "my_VIN"); String sRemote = uAuthority.toString(); String expectedRemote = "UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}"; assertEquals(expectedRemote, sRemote); @@ -82,16 +82,16 @@ public void test_local_uAuthority() { @Test @DisplayName("Test a local uAuthority when one part is empty") public void test_local_uAuthority_one_part_empty() { - UAuthority uAuthority = UAuthority.remote("", "My_VIN"); + UAuthority uAuthority = UAuthority.longRemote("", "My_VIN"); assertFalse(uAuthority.isLocal()); - UAuthority uAuthority2 = UAuthority.remote("VCU", ""); + UAuthority uAuthority2 = UAuthority.longRemote("VCU", ""); assertFalse(uAuthority2.isLocal()); } @Test - @DisplayName("Test a remote uAuthority") + @DisplayName("Test a microRemote uAuthority") public void test_remote_uAuthority() { - UAuthority uAuthority = UAuthority.remote("VCU", "my_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "my_VIN"); assertTrue(uAuthority.device().isPresent()); assertEquals("vcu", uAuthority.device().get()); assertTrue(uAuthority.domain().isPresent()); @@ -101,9 +101,9 @@ public void test_remote_uAuthority() { } @Test - @DisplayName("Test a remote uAuthority with case sensitivity") + @DisplayName("Test a microRemote uAuthority with case sensitivity") public void test_remote_uAuthority_case_sensitive() { - UAuthority uAuthority = UAuthority.remote("VCu", "my_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCu", "my_VIN"); assertTrue(uAuthority.device().isPresent()); assertEquals("vcu", uAuthority.device().get()); assertTrue(uAuthority.domain().isPresent()); @@ -113,9 +113,9 @@ public void test_remote_uAuthority_case_sensitive() { } @Test - @DisplayName("Test a blank remote uAuthority is actually local") + @DisplayName("Test a blank microRemote uAuthority is actually local") public void test_blank_remote_uAuthority_is_local() { - UAuthority uAuthority = UAuthority.remote(" ", " "); + UAuthority uAuthority = UAuthority.longRemote(" ", " "); assertTrue(uAuthority.device().isEmpty()); assertTrue(uAuthority.domain().isEmpty()); assertTrue(uAuthority.isLocal()); @@ -143,7 +143,7 @@ public void test_isLocal() { @Test @DisplayName("Make sure the isRemote() works") public void test_isRemote() { - UAuthority remote = UAuthority.remote("VCU", "my_VIN"); + UAuthority remote = UAuthority.longRemote("VCU", "my_VIN"); assertFalse(remote.isLocal()); assertTrue(remote.isRemote()); assertTrue(remote.isMarkedRemote()); @@ -153,7 +153,7 @@ public void test_isRemote() { @Test @DisplayName("Test creating uAuthority with invalid ip address") public void test_create_uAuthority_with_invalid_ip_address() { - UAuthority remote = UAuthority.remote((InetAddress)null); + UAuthority remote = UAuthority.microRemote((InetAddress)null); String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); assertFalse(remote.address().isPresent()); @@ -165,7 +165,7 @@ public void test_create_uAuthority_with_invalid_ip_address() { public void test_create_uAuthority_with_valid_ip_address() { InetAddress address = Inet6Address.getLoopbackAddress(); - UAuthority remote = UAuthority.remote(address); + UAuthority remote = UAuthority.microRemote(address); String expectedLocal = "UAuthority{device='null', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; InetAddress address2 = remote.address().get(); assertTrue(remote.address().isPresent()); @@ -185,7 +185,7 @@ public void test_create_uAuthority_with_valid_ipv6_address() { e.printStackTrace(); } - UAuthority remote = UAuthority.remote(address); + UAuthority remote = UAuthority.microRemote(address); String expectedLocal = "UAuthority{device='null', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } @@ -193,7 +193,7 @@ public void test_create_uAuthority_with_valid_ipv6_address() { @Test @DisplayName("Test creating uAuthority with valid ipv4 address in the device name") public void test_create_uAuthority_with_valid_ipv4_address_in_device_name() { - UAuthority remote = UAuthority.remote("192.168.1.100", null); + UAuthority remote = UAuthority.longRemote("192.168.1.100", null); String expectedLocal = "UAuthority{device='192.168.1.100', domain='null', address='/192.168.1.100', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } @@ -203,8 +203,8 @@ public void test_create_uAuthority_with_valid_ipv4_address_in_device_name() { @DisplayName("Test isResolved() and isLongForm() with a resolved uAuthority") public void test_isResolved_with_resolved_uAuthority() throws UnknownHostException { UAuthority local = UAuthority.local(); - UAuthority remote = UAuthority.remote("192.168.1.100", null, InetAddress.getByName("192.168.1.100")); - UAuthority remote1 = UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")); + UAuthority remote = UAuthority.resolvedRemote("192.168.1.100", null, InetAddress.getByName("192.168.1.100")); + UAuthority remote1 = UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")); assertTrue(local.isResolved()); assertTrue(local.isLongForm()); assertTrue(remote.isResolved()); @@ -217,8 +217,8 @@ public void test_isResolved_with_resolved_uAuthority() throws UnknownHostExcepti @Test @DisplayName("Test isResolved() and isLongForm() with a unresolved uAuthority") public void test_isResolved_with_unresolved_uAuthority() throws UnknownHostException { - UAuthority remote = UAuthority.remote("vcu", "vin"); - UAuthority remote1 = UAuthority.remote(InetAddress.getByName("192.168.1.100")); + UAuthority remote = UAuthority.longRemote("vcu", "vin"); + UAuthority remote1 = UAuthority.microRemote(InetAddress.getByName("192.168.1.100")); UAuthority remote2 = UAuthority.empty(); assertFalse(remote.isResolved()); assertTrue(remote.isLongForm()); diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 0239b183..a8e1f4df 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -33,7 +33,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; -class UriTest { +class UriPartTest { @Test @DisplayName("Make sure the equals and hash code works") @@ -45,25 +45,25 @@ public void testHashCodeEquals() { @DisplayName("Make sure the toString works") public void testToString() { UAuthority uAuthorityLocal = UAuthority.local(); - UAuthority uAuthorityRemote = UAuthority.remote("VCU", "MY_VIN"); + UAuthority uAuthorityRemote = UAuthority.longRemote("VCU", "MY_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromNameWithInstance("door", "front_left"); UUri uri = new UUri(uAuthorityLocal, use, uResource); - String expected = "Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + + String expected = "UriPart{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + "uEntity=UEntity{name='body.access', version='1', id='null'}, " + "uResource=UResource{name='door', instance='front_left', message='null', id='null'}}"; assertEquals(expected, uri.toString()); UUri uriRemote = new UUri(uAuthorityRemote, use, uResource); - String expectedRemote = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + + String expectedRemote = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + "uEntity=UEntity{name='body.access', version='1', id='null'}, " + "uResource=UResource{name='door', instance='front_left', message='null', id='null'}}"; assertEquals(expectedRemote, uriRemote.toString()); UUri uri2 = new UUri(uAuthorityRemote, use, UResource.empty()); - String expectedUri2 = "Uri{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + + String expectedUri2 = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + "uEntity=UEntity{name='body.access', version='1', id='null'}, " + "uResource=UResource{name='', instance='null', message='null', id='null'}}"; assertEquals(expectedUri2, uri2.toString()); @@ -84,9 +84,9 @@ public void test_create_full_local_uri() { } @Test - @DisplayName("Test creating full remote uri") + @DisplayName("Test creating full microRemote uri") public void test_create_full_remote_uri() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = new UResource("door", "front_left", "Door"); @@ -101,7 +101,7 @@ public void test_create_full_remote_uri() { @Test @DisplayName("Test creating full uri with resource but no message using the constructor") public void test_create_uri_no_message_with_constructor() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); @@ -125,7 +125,7 @@ public void test_create_uri_null_authority() { @Test @DisplayName("Test creating a uri with a null software entity, expect creation with an empty software entity") public void test_create_uri_null_use() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); UResource uResource = UResource.fromNameWithInstance("door", "front_left"); UUri uri = new UUri(uAuthority, null, uResource); @@ -135,7 +135,7 @@ public void test_create_uri_null_use() { @Test @DisplayName("Test creating a uri with a null ulitfi resource, expect creation with an empty resource") public void test_create_uri_null_uResource() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.empty(); @@ -191,32 +191,32 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri11.isResolved()); assertTrue(uri11.isLongForm()); - UUri uri5 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + UUri uri5 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); assertFalse(uri5.isResolved()); assertTrue(uri5.isLongForm()); - UUri uri6 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri6.isResolved()); assertTrue(uri6.isLongForm()); - UUri uri7 = new UUri(UAuthority.remote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri7.isResolved()); assertTrue(uri7.isLongForm()); - UUri uri8 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + UUri uri8 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); assertFalse(uri8.isResolved()); assertTrue(uri8.isLongForm()); - UUri uri9 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri9.isResolved()); assertTrue(uri9.isLongForm()); - UUri uri10 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), new UResource("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri10.isResolved()); assertTrue(uri10.isLongForm()); - UUri uri12 = new UUri(UAuthority.remote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), UResource.fromId((short)2)); + UUri uri12 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), UResource.fromId((short)2)); assertFalse(uri12.isResolved()); assertFalse(uri12.isLongForm()); diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTestPart.java similarity index 90% rename from src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java rename to src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTestPart.java index 6fea31fa..4229ec7c 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTestPart.java @@ -15,7 +15,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -public class BytesUriSerializerTest { +public class BytesUriSerializerTestPart { @Test @DisplayName("Test serialize and deserialize empty content") @@ -67,11 +67,11 @@ public void test_serialize_invalid_uuris() throws UnknownHostException { byte[] bytes2 = UriSerializer.MICRO.serialize(uri2); assertEquals(bytes2.length, 0); - UUri uri3 = new UUri(UAuthority.remote("null", "null"), new UEntity("", null), UResource.forRpc("", (short)1)); + UUri uri3 = new UUri(UAuthority.longRemote("null", "null"), new UEntity("", null), UResource.forRpc("", (short)1)); byte[] bytes3 = UriSerializer.MICRO.serialize(uri3); assertEquals(bytes3.length, 0); - UUri uri4 = new UUri(UAuthority.remote("vcu", "vin", null), new UEntity("", null), UResource.forRpc("", (short)1)); + UUri uri4 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), new UEntity("", null), UResource.forRpc("", (short)1)); byte[] bytes4 = UriSerializer.MICRO.serialize(uri4); assertEquals(bytes4.length, 0); } @@ -79,7 +79,7 @@ public void test_serialize_invalid_uuris() throws UnknownHostException { @Test @DisplayName("Test serialize and deserialize IPv4 UUris") public void test_serialize_ipv4_uri() throws UnknownHostException { - UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("192.168.1.100")); + UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("192.168.1.100")); UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); @@ -92,7 +92,7 @@ public void test_serialize_ipv4_uri() throws UnknownHostException { @Test @DisplayName("Test serialize and deserialize IPv6 UUris") public void test_serialize_ipv6_uri() throws UnknownHostException { - UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); + UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); @@ -105,7 +105,7 @@ public void test_serialize_ipv6_uri() throws UnknownHostException { @Test @DisplayName("Test deserialize with missing information") public void test_deserialize_with_missing_information() throws UnknownHostException { - UAuthority uAuthority = UAuthority.remote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); + UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); UEntity use = UEntity.fromId(1, (short)2); UResource uResource = UResource.fromId((short)3); UUri uri = new UUri(uAuthority, use, uResource); diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTestPart.java similarity index 89% rename from src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java rename to src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTestPart.java index 6c45d1af..044a079a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTestPart.java @@ -1,5 +1,6 @@ package org.eclipse.uprotocol.uri.serializer; +import org.eclipse.uprotocol.uri.datamodel.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -8,9 +9,8 @@ import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -public class StringUriSerializerTest { +public class StringUriSerializerTestPart { @Test @DisplayName("Test using the serializers") @@ -256,7 +256,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_with_version() { } @Test - @DisplayName("Test parse uProtocol uri with remote service only device no domain") + @DisplayName("Test parse uProtocol uri with microRemote service only device no domain") public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() { String uri = "//VCU"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -269,7 +269,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() } @Test - @DisplayName("Test parse uProtocol uri with remote service only device and domain") + @DisplayName("Test parse uProtocol uri with microRemote service only device and domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() { String uri = "//VCU.MY_CAR_VIN"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -283,7 +283,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() } @Test - @DisplayName("Test parse uProtocol uri with remote service only device and cloud domain") + @DisplayName("Test parse uProtocol uri with microRemote service only device and cloud domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_domain() { String uri = "//cloud.uprotocol.example.com"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -297,7 +297,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_do } @Test - @DisplayName("Test parse uProtocol uri with remote service no version") + @DisplayName("Test parse uProtocol uri with microRemote service no version") public void test_parse_protocol_uri_with_remote_service_no_version() { String uri = "//VCU.MY_CAR_VIN/body.access"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -312,7 +312,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version() { } @Test - @DisplayName("Test parse uProtocol uri with remote cloud service no version") + @DisplayName("Test parse uProtocol uri with microRemote cloud service no version") public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { String uri = "//cloud.uprotocol.example.com/body.access"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -327,7 +327,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { } @Test - @DisplayName("Test parse uProtocol uri with remote service with version") + @DisplayName("Test parse uProtocol uri with microRemote service with version") public void test_parse_protocol_uri_with_remote_service_with_version() { String uri = "//VCU.MY_CAR_VIN/body.access/1"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -343,7 +343,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version() { } @Test - @DisplayName("Test parse uProtocol uri with remote cloud service with version") + @DisplayName("Test parse uProtocol uri with microRemote cloud service with version") public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { String uri = "//cloud.uprotocol.example.com/body.access/1"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -359,7 +359,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { } @Test - @DisplayName("Test parse uProtocol uri with remote service no version with resource name only") + @DisplayName("Test parse uProtocol uri with microRemote service no version with resource name only") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access//door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -376,7 +376,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource } @Test - @DisplayName("Test parse uProtocol uri with remote cloud service no version with resource name only") + @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource name only") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access//door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -393,7 +393,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re } @Test - @DisplayName("Test parse uProtocol uri with remote service with version with resource name only") + @DisplayName("Test parse uProtocol uri with microRemote service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -411,7 +411,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour } @Test - @DisplayName("Test parse uProtocol uri with remote cloud service with version with resource name only") + @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access/1/door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -429,7 +429,7 @@ public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_ } @Test - @DisplayName("Test parse uProtocol uri with remote service no version with resource and instance no message") + @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -447,7 +447,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource } @Test - @DisplayName("Test parse uProtocol uri with remote service with version with resource and instance no message") + @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -466,7 +466,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour } @Test - @DisplayName("Test parse uProtocol uri with remote service no version with resource and instance and message") + @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -485,7 +485,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource } @Test - @DisplayName("Test parse uProtocol uri with remote cloud service no version with resource and instance and message") + @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access//door.front_left#Door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -504,7 +504,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re } @Test - @DisplayName("Test parse uProtocol uri with remote service with version with resource and instance and message") + @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -524,7 +524,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour } @Test - @DisplayName("Test parse uProtocol uri with remote cloud service with version with resource and instance and message") + @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access/1/door.front_left#Door"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -544,7 +544,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_ } @Test - @DisplayName("Test parse uProtocol uri with remote service with version with resource with message when there is only device, no domain") + @DisplayName("Test parse uProtocol uri with microRemote service with version with resource with message when there is only device, no domain") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_with_message_device_no_domain() { String uri = "//VCU/body.access/1/door.front_left"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -562,7 +562,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour } @Test - @DisplayName("Test parse uProtocol RPC uri with remote service no version") + @DisplayName("Test parse uProtocol RPC uri with microRemote service no version") public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { String uri = "//bo.cloud/petapp//rpc.response"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -580,7 +580,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { } @Test - @DisplayName("Test parse uProtocol RPC uri with remote service with version") + @DisplayName("Test parse uProtocol RPC uri with microRemote service with version") public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { String uri = "//bo.cloud/petapp/1/rpc.response"; UUri Uri = UriSerializer.LONG.deserialize(uri); @@ -695,100 +695,100 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service no version") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version() { UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority no device with domain with service no version") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority no device with domain with service no version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_device_with_domain_with_service_no_version() { UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.remote("", "MY_CAR_VIN"), use, UResource.empty()); + UUri Uri = new UUri(UAuthority.longRemote("", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//my_car_vin/body.access", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() { UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.empty()); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote cloud authority with service and version") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote cloud authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() { UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.empty()); + UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version with resource") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() { UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service no version with resource") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource() { UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version with resource with instance no message") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote cloud authority with service and version with resource with instance no message") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote cloud authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.remote("cloud", "uprotocol.example.com"), use, UResource.fromNameWithInstance("door", "front_left")); + UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.fromNameWithInstance("door", "front_left")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1/door.front_left", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service no version with resource with instance no message") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service and version with resource with instance and message") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left#Door", uProtocolUri); } @Test - @DisplayName("Test Create a uProtocol URI from an URI Object with a remote authority with service no version with resource with instance and message") + @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_message() { UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.remote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left#Door", uProtocolUri); } @@ -803,9 +803,9 @@ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_ } @Test - @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is remote") + @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is microRemote") public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_remote() { - UAuthority uAuthority = UAuthority.remote("cloud", "uprotocol.example.com"); + UAuthority uAuthority = UAuthority.longRemote("cloud", "uprotocol.example.com"); UEntity use = UEntity.fromName("petapp"); String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("//cloud.uprotocol.example.com/petapp//rpc.response", uProtocolUri); @@ -823,9 +823,9 @@ public void test_build_protocol_uri_from_parts_when_they_are_null() { } @Test - @DisplayName("Test Create a uProtocol URI from the parts of URI Object with a remote authority with service and version with resource") + @DisplayName("Test Create a uProtocol URI from the parts of URI Object with a microRemote authority with service and version with resource") public void test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authority_service_and_version_with_resource() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_CAR_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); String uProtocolUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); @@ -845,7 +845,7 @@ public void test_custom_scheme_no_scheme_empty() { @Test @DisplayName("Test Create a custom URI using no scheme") public void test_custom_scheme_no_scheme() { - UAuthority uAuthority = UAuthority.remote("VCU", "MY_CAR_VIN"); + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_CAR_VIN"); UEntity use = new UEntity("body.access", 1); UResource uResource = UResource.fromName("door"); String ucustomUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); @@ -869,7 +869,7 @@ public void test_parse_local_protocol_uri_with_custom_scheme() { } @Test - @DisplayName("Test parse remote uProtocol uri with custom scheme") + @DisplayName("Test parse microRemote uProtocol uri with custom scheme") public void test_parse_remote_protocol_uri_with_custom_scheme() { String uri = "custom://vcu.vin/body.access//door.front_left#Door"; String uri2 = "//vcu.vin/body.access//door.front_left#Door"; diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriPartValidatorTest.java similarity index 92% rename from src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java rename to src/test/java/org/eclipse/uprotocol/uri/validator/UriPartValidatorTest.java index 4036d9f2..6027df8a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriPartValidatorTest.java @@ -22,6 +22,7 @@ package org.eclipse.uprotocol.uri.validator; +import org.eclipse.uprotocol.uri.datamodel.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -30,13 +31,12 @@ import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; -class UriValidatorTest { +class UriPartValidatorTest { @Test @DisplayName("Test validate blank uri") @@ -45,7 +45,7 @@ public void test_validate_blank_uri() { final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @Test @@ -55,7 +55,7 @@ public void test_validate_uri_with_no_entity_name() { final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @Test @@ -73,7 +73,7 @@ public void test_validate_with_malformed_uri() { final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @@ -84,7 +84,7 @@ public void test_validate_with_blank_uentity_name_uri() { final UStatus status = UriValidator.validate(uri); assertFalse(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + assertEquals("UriPart is missing uSoftware Entity name.", status.msg()); } @Test @@ -101,7 +101,7 @@ public void test_validateRpcMethod_with_invalid_uri() { final UUri uri = UriSerializer.LONG.deserialize("/hartley/echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.msg()); + assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.msg()); } @Test @@ -111,7 +111,7 @@ public void test_validateRpcMethod_with_malformed_uri() { final UStatus status = UriValidator.validateRpcMethod(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @Test @@ -129,7 +129,7 @@ public void test_validateRpcResponse_with_malformed_uri() { final UStatus status = UriValidator.validateRpcResponse(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @Test diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index abc3d9c8..68ba687a 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -66,7 +66,7 @@ public void testToString() { .withCommStatus(5) .build(); assertEquals(String.format("UAttributes{id=%s, type=RESPONSE, priority=LOW, ttl=1000, token='someToken', " + - "sink=Uri{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + + "sink=UriPart{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + "uEntity=UEntity{name='body.access', version='latest', id='null'}, " + "uResource=UResource{name='', instance='null', message='null', id='null'}}, " + "plevel=1, commstatus=5, reqid=%s}", @@ -164,7 +164,7 @@ public void test_create_uattributes_builder_for_basic_rpc_request_with_values() @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC response") public void test_create_uattributes_builder_for_basic_rpc_response() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = UAttributes.forRpcResponse(id, sink, requestId) @@ -185,7 +185,7 @@ public void test_create_uattributes_builder_for_basic_rpc_response() { public void test_create_uattributes_builder_for_basic_rpc_response_with_values() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UAttributes uAttributes = UAttributes.forRpcResponse(id, UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UAttributes uAttributes = UAttributes.forRpcResponse(id, UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), requestId) .withToken("someToken") .withTtl(10000) @@ -345,7 +345,7 @@ public void test_is_uattributes_configured_for_rpc_request_payload() { public void test_scenarios_for_uattributes_not_configured_for_rpc_request_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final String vin = "someVin"; - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", vin)), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", vin)), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -364,7 +364,7 @@ public void test_scenarios_for_uattributes_not_configured_for_rpc_request_payloa public void test_is_uattributes_configured_for_rpc_response_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UUri sink = new UUri(UAuthority.remote("azure", "bo.ultifi.gm.com"), + final UUri sink = new UUri(UAuthority.longRemote("azure", "bo.ultifi.gm.com"), new UEntity("petapp.ultifi.gm.com",1), UResource.empty()); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -379,7 +379,7 @@ public void test_is_uattributes_configured_for_rpc_response_payload() { public void test_scenarios_for_uattributes_not_configured_for_rpc_response_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UUri sink = new UUri(UAuthority.remote("azure", "bo.ultifi.gm.com"), + final UUri sink = new UUri(UAuthority.longRemote("azure", "bo.ultifi.gm.com"), new UEntity("petapp.ultifi.gm.com",1), UResource.empty()); final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index d3a55184..abb5a8fb 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -167,7 +167,7 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_sink() final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @Test @@ -217,7 +217,7 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_reques @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request") public void test_validate_uAttributes_for_rpc_request_message_payload() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -234,7 +234,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload() { @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with all values") public void test_validate_uAttributes_for_rpc_request_message_payload_all_values() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -254,7 +254,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_all_values @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -271,7 +271,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid type") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_type() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -288,7 +288,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ty @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid priority") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_priority() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, null) @@ -305,7 +305,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_pr @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with missing time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_missing_ttl() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -321,7 +321,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_missing_tt @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ttl() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -367,7 +367,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_si @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid permission level") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_permission_level() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -385,7 +385,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_pe @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid communication status") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_communication_status() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -403,7 +403,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_co @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid request id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_request_id() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) @@ -423,7 +423,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_re @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response") public void test_validate_uAttributes_for_rpc_response_message_payload() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -440,7 +440,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload() { @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with all values") public void test_validate_uAttributes_for_rpc_response_message_payload_all_values() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -459,7 +459,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_all_value @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_id() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -476,7 +476,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_i @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid type") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_type() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) @@ -493,7 +493,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_t @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid priority") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_priority() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, null) @@ -510,7 +510,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_p @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid time to live") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_ttl() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -551,13 +551,13 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_s final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + assertEquals("UriPart is missing uSoftware Entity name.", status.msg()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid permission level") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_permission_level() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -575,7 +575,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_p @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid communication status") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_communication_status() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -593,7 +593,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_c @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with missing request id") public void test_validate_uAttributes_for_rpc_response_message_payload_missing_request_id() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) @@ -609,7 +609,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_missing_r @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid request id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_request_id() { - final UUri sink = new UUri(UAuthority.remote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), + final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); final UUID reqid = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), @@ -772,7 +772,7 @@ public void test_validating_invalid_sink_attribute() { assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Uri is empty.", status.msg()); + assertEquals("UriPart is empty.", status.msg()); } @Test From d19bc6459c707ac7cf768849d9307623c9b8625b Mon Sep 17 00:00:00 2001 From: czfdcn Date: Mon, 18 Sep 2023 21:30:00 -0400 Subject: [PATCH 35/52] Fixing all the builds for the refactored code --- .../uprotocol/uri/datamodel/UAuthority.java | 7 +- .../uprotocol/uri/datamodel/UEntity.java | 3 +- .../uprotocol/uri/datamodel/UResource.java | 13 +- .../uri/serializer/LongUriSerializer.java | 25 +-- .../uri/serializer/MicroUriSerializer.java | 4 +- .../uprotocol/uri/validator/UriValidator.java | 2 +- .../utransport/datamodel/UAttributes.java | 4 +- .../factory/CloudEventFactoryTest.java | 58 +++--- .../cloudevent/factory/UCloudEventTest.java | 4 +- .../CloudEventToJsonSerializerTest.java | 4 +- .../CloudEventToProtobufSerializerTest.java | 8 +- .../validate/CloudEventValidatorTest.java | 12 +- .../org/eclipse/uprotocol/rpc/RpcTest.java | 2 +- .../uri/datamodel/UAuthorityTest.java | 4 +- .../uprotocol/uri/datamodel/UEntityTest.java | 111 +++++++--- .../uri/datamodel/UResourceTest.java | 191 +++++++++--------- .../uprotocol/uri/datamodel/UUriTest.java | 58 +++--- ...stPart.java => LongUriSerializerTest.java} | 88 ++++---- ...tPart.java => MicroUriSerializerTest.java} | 42 ++-- ...idatorTest.java => UUriValidatorTest.java} | 4 +- .../utransport/datamodel/UAttributeTest.java | 24 +-- .../validator/UAttributesValidatorTest.java | 46 ++--- 22 files changed, 398 insertions(+), 316 deletions(-) rename src/test/java/org/eclipse/uprotocol/uri/serializer/{StringUriSerializerTestPart.java => LongUriSerializerTest.java} (93%) rename src/test/java/org/eclipse/uprotocol/uri/serializer/{BytesUriSerializerTestPart.java => MicroUriSerializerTest.java} (79%) rename src/test/java/org/eclipse/uprotocol/uri/validator/{UriPartValidatorTest.java => UUriValidatorTest.java} (99%) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 154e97bd..e36d6ba7 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -24,7 +24,6 @@ import java.net.InetAddress; import java.util.Objects; import java.util.Optional; -import org.apache.commons.validator.routines.InetAddressValidator; /** * Data representation of an Authority.
An Authority consists of a device and a domain.
@@ -33,7 +32,7 @@ * An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ public class UAuthority implements UriPart { - private final static UAuthority EMPTY = new UAuthority(null, null, null, false, false); + private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); /** * A device is a logical independent representation of a service bus in different execution environments.
@@ -187,7 +186,7 @@ public boolean isResolved() { */ @Override public boolean isLongForm() { - return device().isPresent(); + return isLocal() || device().isPresent(); } /** @@ -196,7 +195,7 @@ public boolean isLongForm() { */ @Override public boolean isMicroForm() { - return address().isPresent(); + return isLocal() || address().isPresent(); } @Override diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 2a5e9880..0be910c2 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -55,7 +55,7 @@ private UEntity(String name, Integer version, Short id, boolean markedResolved) } public static UEntity resolvedFormat(String name, Integer version, Short id) { - boolean resolved = !name.isEmpty() && version != null && id != null; + boolean resolved = name != null && !name.isEmpty() && id != null; return new UEntity(name, version, id, resolved); } @@ -132,6 +132,7 @@ public boolean isResolved() { * Determine if this software entity can be serialised into a long UUri form. * @return Returns true if this software entity can be serialised into a long UUri form, meaning it has at least a name. */ + @Override public boolean isLongForm() { return !name().isEmpty(); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 85da95c1..df644e62 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -74,7 +74,7 @@ private UResource(String name, String instance, String message, Short id, boolea * @return Returns a UResource that has all the information that is needed to serialise into a long UUri or a micro UUri. */ public static UResource resolved(String name, String instance, String message, Short id) { - boolean resolved = name != null && !name.isEmpty() && id != null; + boolean resolved = name != null && !name.isEmpty() && instance != null && !instance.isEmpty() && id != null; return new UResource(name, instance, message, id, resolved); } @@ -126,6 +126,17 @@ public static UResource forRpcRequest(Short methodId) { return new UResource("rpc", null, null, methodId, false); } + /** + * Build a UResource for rpc request, using both the long and micro format information. + * @param methodName The RPC method name. + * @param methodId The numeric representation method name for the RPC. + * @return Returns a UResource used for an RPC request that could be serialised in long and micro format. + */ + public static UResource forRpcRequest(String methodName, Short methodId) { + boolean resolved = methodName != null && !methodName.isEmpty() && methodId != null; + return new UResource("rpc", methodName, null, methodId, resolved); + } + /** * Static factory method for creating a response resource that is returned from RPC calls
* @return Returns a response resource used for response RPC calls. diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index 049783f7..68553dcf 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -152,7 +152,7 @@ public UUri deserialize(String uProtocolUri) { if (numberOfPartsInUri > 2) { useVersion = uriParts[2]; - uResource = numberOfPartsInUri > 3 ? UResource.parseFromString(uriParts[3]) : UResource.empty(); + uResource = numberOfPartsInUri > 3 ? parseFromString(uriParts[3]) : UResource.empty(); } else { uResource = UResource.empty(); @@ -173,7 +173,7 @@ public UUri deserialize(String uProtocolUri) { if (numberOfPartsInUri > 4) { useVersion = uriParts[4]; - uResource = numberOfPartsInUri > 5 ? UResource.parseFromString(uriParts[5]) : UResource.empty(); + uResource = numberOfPartsInUri > 5 ? parseFromString(uriParts[5]) : UResource.empty(); } else { uResource = UResource.empty(); @@ -193,12 +193,12 @@ public UUri deserialize(String uProtocolUri) { useVersionInt = null; } - return new UUri(uAuthority, new UEntity(useName, useVersionInt), uResource); + return new UUri(uAuthority, UEntity.longFormat(useName, useVersionInt), uResource); } /** - * Static factory method for creating a UResource using a string that contains either the id or - * a name + instance + message. + * Static factory method for creating a UResource using a string that contains + * name + instance + message. * @param resourceString String that contains the UResource information. * @return Returns a UResource object */ @@ -207,24 +207,11 @@ private static UResource parseFromString(String resourceString) { String[] parts = resourceString.split("#"); String nameAndInstance = parts[0]; - // Try and fetch the resource ID if there is one (short form) - Short maybeId = null; - try { - maybeId = Short.parseShort(nameAndInstance); - } catch (NumberFormatException e) { - maybeId = null; - - } - - if (maybeId != null) { - return UResource.fromId(maybeId); - } - String[] nameAndInstanceParts = nameAndInstance.split("\\."); String resourceName = nameAndInstanceParts[0]; String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; String resourceMessage = parts.length > 1 ? parts[1] : null; - return new UResource(resourceName, resourceInstance, resourceMessage); + return UResource.longFormat(resourceName, resourceInstance, resourceMessage); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index aa93f203..4a93e10b 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -190,8 +190,8 @@ else if (type.get() == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LEN int uiVersion = microUri[index++]; return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.microRemote(maybeAddress.get()), - UEntity.fromId(uiVersion, (short)ueId), - UResource.fromId((short)uResourceId)); + UEntity.microFormat((short)ueId, uiVersion == 0 ? null : uiVersion), + UResource.microFormat((short)uResourceId)); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 63fe8d41..3af39ca2 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -58,7 +58,7 @@ public static UStatus validateRpcResponse(UUri uri) { } final UResource uResource = uri.uResource(); - if (!uResource.isRPCMethod() || !uResource.equals(UResource.response())) { + if (!uResource.isRPCMethod() || !uResource.instance().equals(UResource.forRpcResponse().instance())) { return UStatus.failed("Invalid RPC response type.", Code.INVALID_ARGUMENT); } diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java index 4c01ae99..c90bcba7 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java @@ -118,7 +118,7 @@ public static UAttributesBuilder forRpcRequest(UUID id, UUri sink) { */ public static UAttributesBuilder forRpcRequest(UUID id, UAuthority uAuthority, UEntity serviceUEntity, String commandName) { return new UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(new UUri(uAuthority, serviceUEntity, UResource.forRpc(commandName))); + .withSink(new UUri(uAuthority, serviceUEntity, UResource.forRpcRequest(commandName))); } /** @@ -144,7 +144,7 @@ public static UAttributesBuilder forRpcResponse(UUID id, UUri sink, UUID request */ public static UAttributesBuilder forRpcResponse(UUID id, UAuthority uAuthority, UEntity callerUEntity, UUID requestId) { return new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(new UUri(uAuthority, callerUEntity, UResource.fromNameWithInstance("rpc", "response"))) + .withSink(new UUri(uAuthority, callerUEntity, UResource.forRpcResponse())) .withReqId(requestId); } diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index 58ed137c..a696581a 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -50,9 +50,9 @@ class CloudEventFactoryTest { public void test_create_base_cloud_event() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload @@ -92,9 +92,9 @@ public void test_create_base_cloud_event() { public void test_create_base_cloud_event_with_datacontenttype_and_schema() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri ultifiUri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(ultifiUri); // fake payload @@ -140,9 +140,9 @@ public void test_create_base_cloud_event_with_datacontenttype_and_schema() { public void test_create_base_cloud_event_without_attributes() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload @@ -177,9 +177,9 @@ public void test_create_base_cloud_event_without_attributes() { public void test_create_publish_cloud_event() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload @@ -211,13 +211,13 @@ public void test_create_publish_cloud_event() { public void test_create_notification_cloud_event() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // sink - UEntity sinkUse = UEntity.fromName("petapp"); + UEntity sinkUse = UEntity.longFormat("petapp"); UUri sinkUri = new UUri(UAuthority.longRemote("com.gm.bo", "bo"), sinkUse, "OK"); String sink = UriSerializer.LONG.serialize(sinkUri); @@ -255,13 +255,13 @@ public void test_create_notification_cloud_event() { public void test_create_request_cloud_event_from_local_use() { // UriPart for the application requesting the RPC - UEntity sourceUse = UEntity.fromName("petapp"); + UEntity sourceUse = UEntity.longFormat("petapp"); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method UriPart - UEntity methodSoftwareEntityService = new UEntity("body.access", 1); + UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, - UResource.forRpc("UpdateDoor")); + UResource.forRpcRequest("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload @@ -301,14 +301,14 @@ public void test_create_request_cloud_event_from_remote_use() { // UriPart for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); - UEntity sourceUse = new UEntity("petapp", 1); + UEntity sourceUse = UEntity.longFormat("petapp", 1); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method UriPart - UEntity methodSoftwareEntityService = new UEntity("body.access", 1); + UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, - UResource.forRpc("UpdateDoor")); + UResource.forRpcRequest("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload @@ -347,13 +347,13 @@ public void test_create_request_cloud_event_from_remote_use() { public void test_create_response_cloud_event_originating_from_local_use() { // UriPart for the application requesting the RPC - UEntity sourceUse = new UEntity("petapp", 1); + UEntity sourceUse = UEntity.longFormat("petapp", 1); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method UriPart - UEntity methodSoftwareEntityService = new UEntity("body.access", 1); + UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, - UResource.forRpc("UpdateDoor")); + UResource.forRpcRequest("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload @@ -393,15 +393,15 @@ public void test_create_response_cloud_event_originating_from_remote_use() { // UriPart for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); - UEntity sourceUse = UEntity.fromName("petapp"); + UEntity sourceUse = UEntity.longFormat("petapp"); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method UriPart - UEntity methodSoftwareEntityService = new UEntity("body.access", 1); + UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, - UResource.forRpc("UpdateDoor")); + UResource.forRpcRequest("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // fake payload @@ -441,13 +441,13 @@ public void test_create_response_cloud_event_originating_from_remote_use() { public void test_create_a_failed_response_cloud_event_originating_from_local_use() { // UriPart for the application requesting the RPC - UEntity sourceUse = new UEntity("petapp", 1); + UEntity sourceUse = UEntity.longFormat("petapp", 1); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method UriPart - UEntity methodSoftwareEntityService = new UEntity("body.access", 1); + UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, - UResource.forRpc("UpdateDoor")); + UResource.forRpcRequest("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); // additional attributes @@ -485,15 +485,15 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us // UriPart for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); - UEntity sourceUse = UEntity.fromName("petapp"); + UEntity sourceUse = UEntity.longFormat("petapp"); String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method UriPart - UEntity methodSoftwareEntityService = new UEntity("body.access", 1); + UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, - UResource.forRpc("UpdateDoor")); + UResource.forRpcRequest("UpdateDoor")); String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java index 0cc9694f..c6084d76 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java @@ -680,9 +680,9 @@ public void test_pretty_printing_a_cloudevent_without_a_sink() { private CloudEventBuilder buildBaseCloudEventBuilderForTest() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java index 46abd512..05ba34b7 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java @@ -165,9 +165,9 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa final CloudEventSerializer serializer = CloudEventSerializers.JSON.serializer(); // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java index c878be42..caa81dcd 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java @@ -56,8 +56,8 @@ class CloudEventToProtobufSerializerTest { public void test_serialize_and_desirialize_cloud_event_to_protobuf() { // build the source - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("Door", "front_left")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("Door", "front_left", null)); String source = UriSerializer.LONG.serialize(Uri); // fake payload @@ -145,9 +145,9 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa final CloudEventSerializer serializer = CloudEventSerializers.PROTOBUF.serializer(); // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index ca3cfa88..45b14c45 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -599,9 +599,9 @@ void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() { @DisplayName("Test validate rpc topic uri with version, when it is valid") void test_rpc_topic__uri_with_version_when_it_is_valid() { - UEntity use = new UEntity("petapp", 1); + UEntity use = UEntity.longFormat("petapp", 1); UAuthority uAuthority = UAuthority.longRemote("bo", "cloud"); - UResource uResource = UResource.fromNameWithInstance("rpc", "response"); + UResource uResource = UResource.forRpcResponse(); UUri Uri = new UUri(uAuthority, use, uResource); final Status status = CloudEventValidator.validateRpcTopicUri(Uri).toStatus(); @@ -612,9 +612,9 @@ void test_rpc_topic__uri_with_version_when_it_is_valid() { @DisplayName("Test validate rpc topic uri with version, when it is not valid") void test_rpc_topic__uri_with_version_when_it_is_not_valid() { - UEntity use = new UEntity("petapp", 1); + UEntity use = UEntity.longFormat("petapp", 1); UAuthority uAuthority = UAuthority.longRemote("bo", "cloud"); - UResource uResource = UResource.fromNameWithInstance("body.access", "front_left"); + UResource uResource = UResource.longFormat("body.access", "front_left", null); UUri Uri = new UUri(uAuthority, use, uResource); final Status status = CloudEventValidator.validateRpcTopicUri(Uri).toStatus(); @@ -1019,9 +1019,9 @@ void test_response_type_cloudevent_is_not_valid_invalid_source_not_rpc_command() private CloudEventBuilder buildBaseCloudEventBuilderForTest() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); + UResource.longFormat("door", "front_left", "Door")); String source = UriSerializer.LONG.serialize(Uri); // fake payload diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 5e83923d..5fc6ca76 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -548,7 +548,7 @@ private static UUri buildTopic() { private static UAttributes buildUAttributes() { return UAttributes.forRpcRequest( UUIDFactory.Factories.UPROTOCOL.factory().create(), - UUri.rpcResponse(null, UEntity.fromName("hartley"))).build(); + UUri.rpcResponse(null, UEntity.longFormat("hartley"))).build(); } private static CompletableFuture rpcResponse(CompletableFuture invokeMethodResponse) { diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index d7efd780..c8661c11 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -119,7 +119,7 @@ public void test_blank_remote_uAuthority_is_local() { assertTrue(uAuthority.device().isEmpty()); assertTrue(uAuthority.domain().isEmpty()); assertTrue(uAuthority.isLocal()); - assertFalse(uAuthority.isRemote()); + assertTrue(uAuthority.isRemote()); assertTrue(uAuthority.isMarkedRemote()); } @@ -194,7 +194,7 @@ public void test_create_uAuthority_with_valid_ipv6_address() { @DisplayName("Test creating uAuthority with valid ipv4 address in the device name") public void test_create_uAuthority_with_valid_ipv4_address_in_device_name() { UAuthority remote = UAuthority.longRemote("192.168.1.100", null); - String expectedLocal = "UAuthority{device='192.168.1.100', domain='null', address='/192.168.1.100', markedRemote=true}"; + String expectedLocal = "UAuthority{device='192.168.1.100', domain='null', address='null', markedRemote=true}"; assertEquals(expectedLocal, remote.toString()); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 4775690e..1e2eef0a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -39,22 +39,22 @@ public void testHashCodeEquals() { @Test @DisplayName("Make sure the toString works") public void testToString() { - UEntity use = new UEntity("body.access", 1); + UEntity use = UEntity.longFormat("body.access", 1); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); assertEquals(1, use.version().get()); - String expected = "UEntity{name='body.access', version='1', id='null'}"; + String expected = "UEntity{name='body.access', version=1, id=null, markedResolved=false}"; assertEquals(expected, use.toString()); - UEntity use1 = UEntity.fromName("body.access"); - assertEquals("UEntity{name='body.access', version='latest', id='null'}", use1.toString()); + UEntity use1 = UEntity.longFormat("body.access"); + assertEquals("UEntity{name='body.access', version=null, id=null, markedResolved=false}", use1.toString()); } @Test @DisplayName("Test creating a complete USE") public void test_create_use() { - UEntity use = new UEntity("body.access", 1); + UEntity use = UEntity.longFormat("body.access", 1); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); assertEquals(1, use.version().get()); @@ -63,26 +63,26 @@ public void test_create_use() { @Test @DisplayName("Test creating a complete USE with a null name, expect exception") public void test_create_use_null_name() { - Exception exception = assertThrows(NullPointerException.class, () -> new UEntity(null, 1)); + Exception exception = assertThrows(NullPointerException.class, () -> UEntity.longFormat(null, 1)); assertTrue(exception.getMessage().contains(" Software Entity must have a name")); } @Test @DisplayName("Test creating a USE with no version") public void test_create_use_with_no_version() { - UEntity use = new UEntity("body.access", null); + UEntity use = UEntity.longFormat("body.access", null); assertEquals("body.access", use.name()); assertTrue(use.version().isEmpty()); - UEntity use2 = new UEntity("body.access", null); + UEntity use2 = UEntity.longFormat("body.access", null); assertEquals("body.access", use2.name()); assertTrue(use2.version().isEmpty()); } @Test - @DisplayName("Test creating a USE using the fromName static method") - public void test_create_use_with_no_version_using_fromName() { - UEntity use = UEntity.fromName("body.access"); + @DisplayName("Test creating a USE using the longFormat static method") + public void test_create_use_with_no_version_using_longFormat() { + UEntity use = UEntity.longFormat("body.access"); assertEquals("body.access", use.name()); assertTrue(use.version().isEmpty()); } @@ -101,46 +101,46 @@ public void test_is_empty() { UEntity use = UEntity.empty(); assertTrue(use.isEmpty()); - UEntity use2 = new UEntity("", null); + UEntity use2 = UEntity.longFormat("", null); assertTrue(use2.isEmpty()); - UEntity use3 = new UEntity("", 1); + UEntity use3 = UEntity.longFormat("", 1); assertFalse(use3.isEmpty()); - UEntity use4 = new UEntity("petapp", null); + UEntity use4 = UEntity.longFormat("petapp", null); assertFalse(use4.isEmpty()); } @Test @DisplayName("Test creating UEntity with id") public void test_create_use_with_id() { - UEntity use = new UEntity("body.access", 1, (short)0); + UEntity use = UEntity.resolvedFormat("body.access", 1, (short)0); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); assertEquals(1, use.version().get()); assertTrue(use.id().isPresent()); assertEquals((int)0, (int)use.id().get()); - assertEquals("UEntity{name='body.access', version='1', id='0'}", use.toString()); + assertEquals("UEntity{name='body.access', version=1, id=0, markedResolved=true}", use.toString()); } @Test @DisplayName("Test creating UEntity with invalid id") public void test_create_use_with_invalid_id() { - UEntity use = new UEntity("body.access", 1, null); + UEntity use = UEntity.resolvedFormat("body.access", 1, null); assertEquals("body.access", use.name()); assertTrue(use.version().isPresent()); assertEquals(1, use.version().get()); assertFalse(use.id().isPresent()); - assertEquals("UEntity{name='body.access', version='1', id='null'}", use.toString()); + assertEquals("UEntity{name='body.access', version=1, id=null, markedResolved=false}", use.toString()); } @Test @DisplayName("Test isResolved and isLongForm() with valid resolved information") public void test_isResolved_with_valid_resolved_data() { - UEntity use = new UEntity("body.access", 1, (short)0); + UEntity use = UEntity.resolvedFormat("body.access", 1, (short)0); assertTrue(use.isResolved()); assertTrue(use.isLongForm()); - UEntity use3 = new UEntity("2", null, (short)1); + UEntity use3 = UEntity.resolvedFormat("2", null, (short)1); assertTrue(use3.isResolved()); assertTrue(use3.isLongForm()); } @@ -148,17 +148,82 @@ public void test_isResolved_with_valid_resolved_data() { @Test @DisplayName("Test isResolved and isLongForm() with invalid resolved data") public void test_isResolved_with_invalid_resolved_data() { - UEntity use = new UEntity("body.access", 1, null); + UEntity use = UEntity.resolvedFormat("body.access", 1, null); assertFalse(use.isResolved()); assertTrue(use.isLongForm()); - UEntity use2 = UEntity.fromId(null, (short)1); + assertFalse(use.isMicroForm()); + + UEntity use2 = UEntity.microFormat((short)1, null); assertFalse(use2.isResolved()); - assertTrue(use2.isLongForm()); + assertFalse(use2.isLongForm()); + assertTrue(use2.isMicroForm()); UEntity use3 = UEntity.empty(); assertFalse(use3.isResolved()); assertFalse(use3.isLongForm()); + assertFalse(use3.isMicroForm()); + + UEntity use4 = UEntity.resolvedFormat("body.access", 1, (short)4); + assertTrue(use4.isResolved()); + assertTrue(use4.isLongForm()); + assertTrue(use4.isMicroForm()); } + @Test + @DisplayName("Test create UEntity calling microFormat with valid id") + public void test_create_use_with_valid_id() { + UEntity use = UEntity.microFormat((short)1); + assertEquals("UEntity{name='', version=null, id=1, markedResolved=false}", use.toString()); + assertTrue(use.id().isPresent()); + assertFalse(use.version().isPresent()); + assertFalse(use.isLongForm()); + assertFalse(use.isResolved()); + assertTrue(use.isMicroForm()); + } + + + @Test + @DisplayName("Test create resolvedFormat with various scenarios passed to the api") + public void test_create_use_with_valid_id_and_version() { + UEntity use = UEntity.resolvedFormat("body.access", 1, (short)1); + assertEquals("UEntity{name='body.access', version=1, id=1, markedResolved=true}", use.toString()); + assertTrue(use.id().isPresent()); + assertEquals(use.version().get(), (short)1); + assertTrue(use.isLongForm()); + assertTrue(use.isResolved()); + assertTrue(use.isMicroForm()); + UEntity use2 = UEntity.resolvedFormat("body.access", null, (short)1); + assertEquals("UEntity{name='body.access', version=null, id=1, markedResolved=true}", use2.toString()); + assertTrue(use2.id().isPresent()); + assertFalse(use2.version().isPresent()); + assertTrue(use2.isLongForm()); + assertTrue(use2.isResolved()); + assertTrue(use2.isMicroForm()); + + UEntity use3 = UEntity.resolvedFormat("body.access", 1, null); + assertEquals("UEntity{name='body.access', version=1, id=null, markedResolved=false}", use3.toString()); + assertFalse(use3.id().isPresent()); + assertEquals(use3.version().get(), (short)1); + assertTrue(use3.isLongForm()); + assertFalse(use3.isResolved()); + assertFalse(use3.isMicroForm()); + + UEntity use4 = UEntity.resolvedFormat("body.access", null, null); + assertEquals("UEntity{name='body.access', version=null, id=null, markedResolved=false}", use4.toString()); + assertFalse(use4.id().isPresent()); + assertFalse(use4.version().isPresent()); + assertTrue(use4.isLongForm()); + assertFalse(use4.isResolved()); + assertFalse(use4.isMicroForm()); + + UEntity use5 = UEntity.resolvedFormat("", null, null); + assertEquals("UEntity{name='', version=null, id=null, markedResolved=false}", use5.toString()); + assertTrue(use5.name().isEmpty()); + assertFalse(use5.id().isPresent()); + assertFalse(use5.version().isPresent()); + assertFalse(use5.isLongForm()); + assertFalse(use5.isResolved()); + assertFalse(use5.isMicroForm()); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 622cdf32..fda1da77 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -38,15 +38,15 @@ public void testHashCodeEquals() { @Test @DisplayName("Make sure the toString works") public void testToString() { - UResource uResource = new UResource("door", "front_left", "Door"); - String expected = "UResource{name='door', instance='front_left', message='Door', id='null'}"; + UResource uResource = UResource.longFormat("door", "front_left", "Door"); + String expected = "UResource{name='door', instance='front_left', message='Door', id=null, markedResolved=false}"; assertEquals(expected, uResource.toString()); } @Test @DisplayName("Test creating a complete Resource") public void test_create_Resource() { - UResource uResource = new UResource("door", "front_left", "Door"); + UResource uResource = UResource.longFormat("door", "front_left", "Door"); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); @@ -54,29 +54,15 @@ public void test_create_Resource() { assertEquals("Door", uResource.message().get()); } - @Test - @DisplayName("Test creating a complete Resource with a null name, expect exception") - public void test_create_Resource_null_name() { - Exception exception = assertThrows(NullPointerException.class, () -> new UResource(null, "front_left", "Door")); - assertTrue(exception.getMessage().contains(" Resource must have a name.")); - } - - @Test - @DisplayName("Test creating an Resource for RPC command with a null command name, expect exception") - public void test_create_Resource_for_rpc_command_null_name() { - Exception exception = assertThrows(NullPointerException.class, () -> UResource.forRpc(null)); - assertTrue(exception.getMessage().contains(" Resource must have a command name.")); - } - @Test @DisplayName("Test creating a Resource with no instance and no message") public void test_create_Resource_with_no_instance_and_no_message() { - UResource uResource = new UResource("door", " ", " "); + UResource uResource = UResource.longFormat("door", " ", " "); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); - UResource uResource2 = new UResource("door", null, null); + UResource uResource2 = UResource.longFormat("door", null, null); assertEquals("door", uResource2.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); @@ -85,7 +71,7 @@ public void test_create_Resource_with_no_instance_and_no_message() { @Test @DisplayName("Test creating a Resource using the fromName static method") public void test_create_Resource_with_no_instance_and_no_message_using_fromName() { - UResource uResource = UResource.fromName("door"); + UResource uResource = UResource.longFormat("door"); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); @@ -94,7 +80,7 @@ public void test_create_Resource_with_no_instance_and_no_message_using_fromName( @Test @DisplayName("Test creating a Resource using the fromNameWithInstance static method") public void test_create_Resource_with_no_message_using_fromName() { - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); + UResource uResource = UResource.longFormat("door", "front_left", null); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); @@ -104,7 +90,7 @@ public void test_create_Resource_with_no_message_using_fromName() { @Test @DisplayName("Test creating a Resource for an RPC command on the resource") public void test_create_Resource_for_rpc_commands() { - UResource uResource = UResource.forRpc("UpdateDoor"); + UResource uResource = UResource.forRpcRequest("UpdateDoor"); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("UpdateDoor", uResource.instance().get()); @@ -114,40 +100,18 @@ public void test_create_Resource_for_rpc_commands() { @Test @DisplayName("Test if the resource represents an RPC method call") public void test_Resource_represents_an_rpc_method_call() { - UResource uResource = UResource.fromNameWithInstance("rpc", "UpdateDoor"); + UResource uResource = UResource.forRpcRequest("UpdateDoor"); assertTrue(uResource.isRPCMethod()); } @Test @DisplayName("Test if the resource represents a resource and not an RPC method call") public void test_Resource_represents_a_resource_and_not_an_rpc_method_call() { - UResource uResource = UResource.fromName("door"); + UResource uResource = UResource.longFormat("door"); assertFalse(uResource.isRPCMethod()); } - @Test - @DisplayName("Test returning a name with instance when both name and instance are configured") - public void test_returning_a_name_with_instance_from_uResource_when_name_and_instance_are_configured() { - UResource uResource = UResource.fromNameWithInstance("doors", "front_left"); - final String nameWithInstance = uResource.nameWithInstance(); - assertEquals("doors.front_left", nameWithInstance); - } - @Test - @DisplayName("Test returning a name with instance when only name is configured") - public void test_returning_a_name_with_instance_from_uResource_when_only_name_is_configured() { - UResource uResource = UResource.fromName("door"); - final String nameWithInstance = uResource.nameWithInstance(); - assertEquals("door", nameWithInstance); - } - - @Test - @DisplayName("Test returning a name with instance when all properties are configured") - public void test_returning_a_name_with_instance_from_uResource_when_all_properties_are_configured() { - UResource uResource = new UResource("doors", "front_left", "Door"); - final String nameWithInstance = uResource.nameWithInstance(); - assertEquals("doors.front_left", nameWithInstance); - } @Test @DisplayName("Test creating an empty Resource using the empty static method") @@ -164,20 +128,20 @@ public void test_is_empty() { UResource uResource = UResource.empty(); assertTrue(uResource.isEmpty()); - UResource uResource2 = new UResource("", null, null); + UResource uResource2 = UResource.longFormat("", null, null); assertTrue(uResource2.isEmpty()); - UResource uResource3 = new UResource("", "front_left", null); + UResource uResource3 = UResource.longFormat("", "front_left", null); assertFalse(uResource3.isEmpty()); - UResource uResource4 = new UResource("", null, "Door"); + UResource uResource4 = UResource.longFormat("", null, "Door"); assertFalse(uResource4.isEmpty()); } @Test @DisplayName("Test creating an RPC response Resource using the response static method") public void test_create_rpc_response_using_response_method() { - UResource uResource = UResource.response(); + UResource uResource = UResource.forRpcResponse(); assertFalse(uResource.name().isEmpty()); assertEquals("rpc", uResource.name()); assertEquals("response", uResource.instance().orElse("")); @@ -187,7 +151,7 @@ public void test_create_rpc_response_using_response_method() { @Test @DisplayName("Test creating an UResource with valid id") public void test_create_UResource_with_valid_id() { - UResource uResource = new UResource("door", "front_left", "Door", (short)5); + UResource uResource = UResource.resolved("door", "front_left", "Door", (short)5); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); @@ -195,132 +159,165 @@ public void test_create_UResource_with_valid_id() { assertEquals("Door", uResource.message().get()); assertTrue(uResource.id().isPresent()); assertEquals((int)5, (int)uResource.id().get()); - assertEquals("UResource{name='door', instance='front_left', message='Door', id='5'}", uResource.toString()); + assertEquals("UResource{name='door', instance='front_left', message='Door', id=5, markedResolved=true}", uResource.toString()); } @Test @DisplayName("Test creating an UResource with invalid id") public void test_create_UResource_with_invalid_id() { - UResource uResource = new UResource("door", "front_left", "Door", null); + UResource uResource = UResource.resolved("door", "front_left", "Door", null); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); assertTrue(uResource.message().isPresent()); assertEquals("Door", uResource.message().get()); assertFalse(uResource.id().isPresent()); - assertEquals("UResource{name='door', instance='front_left', message='Door', id='null'}", uResource.toString()); + assertEquals("UResource{name='door', instance='front_left', message='Door', id=null, markedResolved=false}", uResource.toString()); } @Test @DisplayName("Test creating an UResource by calling fromId static method") public void test_create_UResource_by_calling_fromId_static_method() { - UResource uResource = UResource.fromId((short)5); - assertEquals("unknown", uResource.name()); + UResource uResource = UResource.microFormat((short)5); + assertEquals("", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); assertTrue(uResource.id().isPresent()); assertEquals((int)5, (int)uResource.id().get()); - assertEquals("UResource{name='unknown', instance='null', message='null', id='5'}", uResource.toString()); + assertEquals("UResource{name='', instance='null', message='null', id=5, markedResolved=false}", uResource.toString()); } @Test @DisplayName("Test creating a response UResource by calling fromId") public void test_create_response_UResource_by_calling_fromId() { - UResource uResource = UResource.fromId((short)0); + UResource uResource = UResource.forRpcResponse(); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("response", uResource.instance().get()); assertTrue(uResource.message().isEmpty()); assertTrue(uResource.id().isPresent()); assertEquals((int)0, (int)uResource.id().get()); - assertEquals("UResource{name='rpc', instance='response', message='null', id='0'}", uResource.toString()); + assertEquals("UResource{name='rpc', instance='response', message='null', id=0, markedResolved=true}", uResource.toString()); } @Test @DisplayName("Test creating a response UResource passing name, instance, and id") public void test_create_response_UResource_passing_name_instance_and_id() { - UResource uResource = new UResource("rpc", "response", null, (short)0); + UResource uResource = UResource.resolved("rpc", "response", null, (short)0); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("response", uResource.instance().get()); assertTrue(uResource.message().isEmpty()); assertTrue(uResource.id().isPresent()); assertEquals((int)0, (int)uResource.id().get()); - assertEquals("UResource{name='rpc', instance='response', message='null', id='0'}", uResource.toString()); + assertEquals("UResource{name='rpc', instance='response', message='null', id=0, markedResolved=true}", uResource.toString()); } @Test @DisplayName("Test creating a request UResource passing name, instance, and id") public void test_create_request_UResource_passing_name_instance_and_id() { - UResource uResource = new UResource("rpc", null, null, (short)0); + UResource uResource = UResource.resolved("rpc", null, null, (short)0); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); assertTrue(uResource.id().isPresent()); assertEquals((int)0, (int)uResource.id().get()); - assertEquals("UResource{name='rpc', instance='null', message='null', id='0'}", uResource.toString()); + assertEquals("UResource{name='rpc', instance='null', message='null', id=0, markedResolved=false}", uResource.toString()); } @Test @DisplayName("Test isResolved with resolved UResources") public void test_isResolved_with_resolved_UResources() { - UResource uResource = new UResource("door", "front_left", "Door", (short)5); + UResource uResource = UResource.resolved("door", "front_left", "Door", (short)5); assertTrue(uResource.isResolved()); - UResource uResource2 = UResource.response(); + UResource uResource2 = UResource.forRpcResponse(); assertTrue(uResource2.isResolved()); - UResource uResource3 = UResource.forRpc("UpdateDoor", (short)5); + UResource uResource3 = UResource.forRpcRequest("UpdateDoor", (short)5); assertTrue(uResource3.isResolved()); } @Test @DisplayName("Test isResolved and isLongForm with unresolved UResources") public void test_isResolved_with_unresolved_UResources() { - UResource uResource = new UResource("door", "front_left", "Door", null); + UResource uResource = UResource.resolved("door", "front_left", "Door", null); assertFalse(uResource.isResolved()); assertTrue(uResource.isLongForm()); - UResource uResource2 = UResource.fromName("door"); + UResource uResource2 = UResource.longFormat("door"); assertFalse(uResource2.isResolved()); assertFalse(uResource2.isLongForm()); - UResource uResource3 = UResource.forRpc("UpdateDoor"); + UResource uResource3 = UResource.forRpcRequest("UpdateDoor"); assertFalse(uResource3.isResolved()); assertTrue(uResource3.isLongForm()); - UResource uResource4 = UResource.fromId((short)4); + UResource uResource4 = UResource.microFormat((short)4); assertFalse(uResource4.isResolved()); assertFalse(uResource4.isLongForm()); - UResource uResource5 = UResource.fromNameWithInstance("door", "front_left"); + UResource uResource5 = UResource.longFormat("door", "front_left", null); assertFalse(uResource5.isResolved()); - assertFalse(uResource5.isLongForm()); + assertTrue(uResource5.isLongForm()); } @Test - @DisplayName("Test parseFromString with valid Short Form UResource string") - public void test_parseFromString_with_valid_Long_Form_UResource_string() { - UResource uResource = UResource.parseFromString("0"); - assertEquals("UResource{name='rpc', instance='response', message='null', id='0'}", uResource.toString()); - assertTrue(uResource.id().isPresent()); - assertEquals(uResource.id().get(), (short)0); - - UResource uResource2 = UResource.parseFromString("1"); - assertEquals("UResource{name='unknown', instance='null', message='null', id='1'}", uResource2.toString()); - assertTrue(uResource2.id().isPresent()); - assertEquals(uResource2.id().get(), (short)1); - } + @DisplayName("Test resolved API with all possible combinations of the APIs passed valid and invalid") + public void test_resolved_API_with_all_possible_combinations_of_the_APIs_passed_valid_and_invalid() { + UResource uResource = UResource.resolved("door", "front_left", "Door", (short)5); + assertTrue(uResource.isResolved()); + UResource uResource2 = UResource.resolved("door", "front_left", "Door", null); + assertFalse(uResource2.isResolved()); + UResource uResource3 = UResource.resolved("door", "front_left", null, (short)5); + assertTrue(uResource3.isResolved()); + UResource uResource4 = UResource.resolved("door", "front_left", null, null); + assertFalse(uResource4.isResolved()); + UResource uResource5 = UResource.resolved("door", null, "Door", (short)5); + assertFalse(uResource5.isResolved()); + UResource uResource6 = UResource.resolved("door", null, "Door", null); + assertFalse(uResource6.isResolved()); + UResource uResource7 = UResource.resolved("door", null, null, (short)5); + assertFalse(uResource7.isResolved()); + UResource uResource8 = UResource.resolved("door", null, null, null); + assertFalse(uResource8.isResolved()); + UResource uResource9 = UResource.resolved(null, "front_left", "Door", (short)5); + assertFalse(uResource9.isResolved()); + UResource uResource10 = UResource.resolved(null, "front_left", "Door", null); + assertFalse(uResource10.isResolved()); + UResource uResource11 = UResource.resolved(null, "front_left", null, (short)5); + assertFalse(uResource11.isResolved()); + UResource uResource12 = UResource.resolved(null, "front_left", null, null); + assertFalse(uResource12.isResolved()); + UResource uResource13 = UResource.resolved(null, null, "Door", (short)5); + assertFalse(uResource13.isResolved()); + UResource uResource14 = UResource.resolved(null, null, "Door", null); + assertFalse(uResource14.isResolved()); + UResource uResource15 = UResource.resolved(null, null, null, (short)5); + assertFalse(uResource15.isResolved()); + UResource uResource16 = UResource.resolved(null, null, null, null); + assertFalse(uResource16.isResolved()); + } @Test - @DisplayName("Test parseFromString with missing instance and or message") - public void test_parseFromString_with_missing_instance_and_or_message() { - UResource uResource = UResource.parseFromString("door"); - assertEquals("UResource{name='door', instance='null', message='null', id='null'}", uResource.toString()); - assertTrue(uResource.id().isEmpty()); - - UResource uResource1 = UResource.parseFromString("door.front_left"); - assertEquals("UResource{name='door', instance='front_left', message='null', id='null'}", uResource1.toString()); - assertTrue(uResource1.id().isEmpty()); - - UResource uResource5 = UResource.parseFromString("door.front_left#Door"); - assertEquals("UResource{name='door', instance='front_left', message='Door', id='null'}", uResource5.toString()); - assertTrue(uResource5.id().isEmpty()); + @DisplayName("Test forRpcRequest with null and valid short value") + public void test_forRpcRequest_with_null_and_valid_short_value() { + UResource uResource = UResource.forRpcRequest("UpdateDoor", (short)5); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isPresent()); + assertEquals("UpdateDoor", uResource.instance().get()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isPresent()); + assertEquals((int)5, (int)uResource.id().get()); + assertTrue(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertTrue(uResource.isRPCMethod()); + assertTrue(uResource.isMicroForm()); + + UResource uResource2 = UResource.forRpcRequest((Short)null); + assertEquals("rpc", uResource2.name()); + assertFalse(uResource2.instance().isPresent()); + assertTrue(uResource2.message().isEmpty()); + assertFalse(uResource2.id().isPresent()); + assertFalse(uResource2.isResolved()); + assertFalse(uResource2.isLongForm()); + assertTrue(uResource2.isRPCMethod()); + //assertFalse(uResource.isMicroForm()); } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index a8e1f4df..014cfc0b 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -46,26 +46,26 @@ public void testHashCodeEquals() { public void testToString() { UAuthority uAuthorityLocal = UAuthority.local(); UAuthority uAuthorityRemote = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", 1); - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); + UEntity use = UEntity.longFormat("body.access", 1); + UResource uResource = UResource.longFormat("door", "front_left", null); UUri uri = new UUri(uAuthorityLocal, use, uResource); String expected = "UriPart{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + - "uEntity=UEntity{name='body.access', version='1', id='null'}, " + - "uResource=UResource{name='door', instance='front_left', message='null', id='null'}}"; + "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + + "uResource=UResource{name='door', instance='front_left', message='null', id=null, markedResolved=false}}"; assertEquals(expected, uri.toString()); UUri uriRemote = new UUri(uAuthorityRemote, use, uResource); String expectedRemote = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + - "uEntity=UEntity{name='body.access', version='1', id='null'}, " + - "uResource=UResource{name='door', instance='front_left', message='null', id='null'}}"; + "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + + "uResource=UResource{name='door', instance='front_left', message='null', id=null, markedResolved=false}}"; assertEquals(expectedRemote, uriRemote.toString()); UUri uri2 = new UUri(uAuthorityRemote, use, UResource.empty()); String expectedUri2 = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + - "uEntity=UEntity{name='body.access', version='1', id='null'}, " + - "uResource=UResource{name='', instance='null', message='null', id='null'}}"; + "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + + "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}"; assertEquals(expectedUri2, uri2.toString()); } @@ -73,8 +73,8 @@ public void testToString() { @DisplayName("Test creating full local uri") public void test_create_full_local_uri() { UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.fromName("body.access"); - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); + UEntity use = UEntity.longFormat("body.access"); + UResource uResource = UResource.longFormat("door", "front_left", null); UUri uri = new UUri(uAuthority, use, uResource); @@ -87,8 +87,8 @@ public void test_create_full_local_uri() { @DisplayName("Test creating full microRemote uri") public void test_create_full_remote_uri() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", 1); - UResource uResource = new UResource("door", "front_left", "Door"); + UEntity use = UEntity.longFormat("body.access", 1); + UResource uResource = UResource.longFormat("door", "front_left", "Door"); UUri uri = new UUri(uAuthority, use, uResource); @@ -102,8 +102,8 @@ public void test_create_full_remote_uri() { @DisplayName("Test creating full uri with resource but no message using the constructor") public void test_create_uri_no_message_with_constructor() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", 1); - UResource uResource = UResource.fromName("door"); + UEntity use = UEntity.longFormat("body.access", 1); + UResource uResource = UResource.longFormat("door"); UUri uri = new UUri(uAuthority, use, "door"); @@ -115,8 +115,8 @@ public void test_create_uri_no_message_with_constructor() { @Test @DisplayName("Test creating a uri with a null authority, expect creation with an empty authority") public void test_create_uri_null_authority() { - UEntity use = new UEntity("body.access", 1); - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); + UEntity use = UEntity.longFormat("body.access", 1); + UResource uResource = UResource.longFormat("door", "front_left", null); UUri uri = new UUri(null, use, uResource); assertEquals(UAuthority.empty(), uri.uAuthority()); @@ -126,7 +126,7 @@ public void test_create_uri_null_authority() { @DisplayName("Test creating a uri with a null software entity, expect creation with an empty software entity") public void test_create_uri_null_use() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UResource uResource = UResource.fromNameWithInstance("door", "front_left"); + UResource uResource = UResource.longFormat("door", "front_left", null); UUri uri = new UUri(uAuthority, null, uResource); assertEquals(UEntity.empty(), uri.uEntity()); @@ -136,7 +136,7 @@ public void test_create_uri_null_use() { @DisplayName("Test creating a uri with a null ulitfi resource, expect creation with an empty resource") public void test_create_uri_null_uResource() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = new UEntity("body.access", 1); + UEntity use = UEntity.longFormat("body.access", 1); UResource uResource = UResource.empty(); UUri uri = new UUri(uAuthority, use, uResource); @@ -175,48 +175,48 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri.isResolved()); assertFalse(uri.isLongForm()); - UUri uri2 = new UUri(UAuthority.local(), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); assertFalse(uri2.isResolved()); assertTrue(uri2.isLongForm()); - UUri uri3 = new UUri(UAuthority.local(), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri3 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri3.isResolved()); assertTrue(uri3.isLongForm()); - UUri uri4 = new UUri(UAuthority.local(), new UEntity("Hartley", null, (short)2), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri4 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri4.isResolved()); assertTrue(uri4.isLongForm()); - UUri uri11 = new UUri(UAuthority.local(), new UEntity("Hartley", null, (short)2), UResource.forRpc("Raise")); + UUri uri11 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.forRpcRequest("Raise")); assertFalse(uri11.isResolved()); assertTrue(uri11.isLongForm()); - UUri uri5 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + UUri uri5 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); assertFalse(uri5.isResolved()); assertTrue(uri5.isLongForm()); - UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri6.isResolved()); assertTrue(uri6.isLongForm()); - UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri7.isResolved()); assertTrue(uri7.isLongForm()); - UUri uri8 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), UResource.forRpc("Raise")); + UUri uri8 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); assertFalse(uri8.isResolved()); assertTrue(uri8.isLongForm()); - UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.fromName("Hartley"), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri9.isResolved()); assertTrue(uri9.isLongForm()); - UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), new UResource("Raise", "Salary", "Bonus", (short)1)); + UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri10.isResolved()); assertTrue(uri10.isLongForm()); - UUri uri12 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), new UEntity("Hartley", null, (short)2), UResource.fromId((short)2)); + UUri uri12 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.microFormat((short)2)); assertFalse(uri12.isResolved()); assertFalse(uri12.isLongForm()); diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTestPart.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java similarity index 93% rename from src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTestPart.java rename to src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index 044a079a..8cae5c2a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/StringUriSerializerTestPart.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -10,12 +10,12 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; -public class StringUriSerializerTestPart { +public class LongUriSerializerTest { @Test @DisplayName("Test using the serializers") public void test_using_the_serializers() { - final UUri uri = new UUri(UAuthority.local(), UEntity.fromName("hartley"), UResource.forRpc("raise")); + final UUri uri = new UUri(UAuthority.local(), UEntity.longFormat("hartley"), UResource.forRpcRequest("raise")); final String strUri = UriSerializer.LONG.serialize(uri); assertEquals("/hartley//rpc.raise", strUri); final UUri uri2 = UriSerializer.LONG.deserialize(strUri); @@ -36,6 +36,9 @@ public void test_parse_protocol_uri_when_is_empty_string() { String uri = ""; UUri Uri = UriSerializer.LONG.deserialize(uri); assertTrue(Uri.isEmpty()); + + String uri2 = UriSerializer.LONG.serialize(null); + assertTrue(uri2.isEmpty()); } @Test @@ -46,6 +49,9 @@ public void test_parse_protocol_uri_with_schema_and_slash() { assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); + + String uri2 = UriSerializer.LONG.serialize(UUri.empty()); + assertTrue(uri2.isEmpty()); } @Test @@ -617,7 +623,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { @DisplayName("Test Create a uProtocol URI from an URI object with an empty USE") public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { UEntity use = UEntity.empty(); - UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/", uProtocolUri); } @@ -625,7 +631,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version() { - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access", uProtocolUri); @@ -634,7 +640,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version() { - UEntity use = new UEntity("body.access", 1); + UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1", uProtocolUri); @@ -643,8 +649,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource() { - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access//door", uProtocolUri); } @@ -652,8 +658,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.local(), use, UResource.fromName("door")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1/door", uProtocolUri); } @@ -661,8 +667,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_message() { - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access//door.front_left", uProtocolUri); } @@ -670,8 +676,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_message() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.local(), use, UResource.fromNameWithInstance("door", "front_left")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1/door.front_left", uProtocolUri); } @@ -679,8 +685,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_message() { - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access//door.front_left#Door", uProtocolUri); } @@ -688,8 +694,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_message() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.local(), use, new UResource("door", "front_left", "Door")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("/body.access/1/door.front_left#Door", uProtocolUri); } @@ -697,7 +703,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version() { - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access", uProtocolUri); @@ -706,7 +712,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority no device with domain with service no version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_device_with_domain_with_service_no_version() { - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//my_car_vin/body.access", uProtocolUri); @@ -715,7 +721,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_ @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() { - UEntity use = new UEntity("body.access", 1); + UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri); @@ -724,7 +730,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote cloud authority with service and version") public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() { - UEntity use = new UEntity("body.access", 1); + UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.empty()); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri); @@ -733,8 +739,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -742,8 +748,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource() { - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromName("door")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door", uProtocolUri); } @@ -751,8 +757,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left", uProtocolUri); } @@ -760,8 +766,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote cloud authority with service and version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.fromNameWithInstance("door", "front_left")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1/door.front_left", uProtocolUri); } @@ -769,8 +775,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource with instance no message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_message() { - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.fromNameWithInstance("door", "front_left")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left", uProtocolUri); } @@ -778,8 +784,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { - UEntity use = new UEntity("body.access", 1); - UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); + UEntity use = UEntity.longFormat("body.access", 1); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left#Door", uProtocolUri); } @@ -787,8 +793,8 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource with instance and message") public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_message() { - UEntity use = UEntity.fromName("body.access"); - UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, new UResource("door", "front_left", "Door")); + UEntity use = UEntity.longFormat("body.access"); + UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = UriSerializer.LONG.serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left#Door", uProtocolUri); } @@ -797,7 +803,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is local") public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_local() { UAuthority uAuthority = UAuthority.local(); - UEntity use = new UEntity("petapp", 1); + UEntity use = UEntity.longFormat("petapp", 1); String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("/petapp/1/rpc.response", uProtocolUri); } @@ -806,7 +812,7 @@ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_ @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is microRemote") public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_remote() { UAuthority uAuthority = UAuthority.longRemote("cloud", "uprotocol.example.com"); - UEntity use = UEntity.fromName("petapp"); + UEntity use = UEntity.longFormat("petapp"); String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("//cloud.uprotocol.example.com/petapp//rpc.response", uProtocolUri); } @@ -826,8 +832,8 @@ public void test_build_protocol_uri_from_parts_when_they_are_null() { @DisplayName("Test Create a uProtocol URI from the parts of URI Object with a microRemote authority with service and version with resource") public void test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authority_service_and_version_with_resource() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_CAR_VIN"); - UEntity use = new UEntity("body.access", 1); - UResource uResource = UResource.fromName("door"); + UEntity use = UEntity.longFormat("body.access", 1); + UResource uResource = UResource.longFormat("door"); String uProtocolUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -846,8 +852,8 @@ public void test_custom_scheme_no_scheme_empty() { @DisplayName("Test Create a custom URI using no scheme") public void test_custom_scheme_no_scheme() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_CAR_VIN"); - UEntity use = new UEntity("body.access", 1); - UResource uResource = UResource.fromName("door"); + UEntity use = UEntity.longFormat("body.access", 1); + UResource uResource = UResource.longFormat("door"); String ucustomUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", ucustomUri); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTestPart.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java similarity index 79% rename from src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTestPart.java rename to src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java index 4229ec7c..03cb9ef5 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/BytesUriSerializerTestPart.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java @@ -15,7 +15,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -public class BytesUriSerializerTestPart { +public class MicroUriSerializerTest + { @Test @DisplayName("Test serialize and deserialize empty content") @@ -44,8 +45,8 @@ public void test_null() { @DisplayName("Test happy path Byte serialization of local UUri") public void test_serialize_uri() { UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.fromId(1, (short)2); - UResource uResource = UResource.fromId((short)3); + UEntity use = UEntity.microFormat((short)2, 1); + UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); @@ -56,22 +57,37 @@ public void test_serialize_uri() { } + @Test + @DisplayName("Test happy path with null version") + public void test_serialize_uri_without_version() { + UAuthority uAuthority = UAuthority.local(); + UEntity use = UEntity.microFormat((short)2, null); + UResource uResource = UResource.microFormat((short)3); + + UUri uri = new UUri(uAuthority, use, uResource); + + byte[] bytes = UriSerializer.MICRO.serialize(uri); + UUri uri2 = UriSerializer.MICRO.deserialize(bytes); + + assertEquals(uri, uri2); + } + @Test @DisplayName("Test serialize invalid UUris") public void test_serialize_invalid_uuris() throws UnknownHostException { - UUri uri = new UUri(UAuthority.local(), UEntity.fromId(null, (short)1), UResource.empty()); + UUri uri = new UUri(UAuthority.local(), UEntity.microFormat((short)1, null), UResource.empty()); byte[] bytes = UriSerializer.MICRO.serialize(uri); assertEquals(bytes.length, 0); - UUri uri2 = new UUri(UAuthority.local(), new UEntity("", null), UResource.forRpc("", (short)1)); + UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); byte[] bytes2 = UriSerializer.MICRO.serialize(uri2); assertEquals(bytes2.length, 0); - UUri uri3 = new UUri(UAuthority.longRemote("null", "null"), new UEntity("", null), UResource.forRpc("", (short)1)); + UUri uri3 = new UUri(UAuthority.longRemote("null", "null"), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); byte[] bytes3 = UriSerializer.MICRO.serialize(uri3); assertEquals(bytes3.length, 0); - UUri uri4 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), new UEntity("", null), UResource.forRpc("", (short)1)); + UUri uri4 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); byte[] bytes4 = UriSerializer.MICRO.serialize(uri4); assertEquals(bytes4.length, 0); } @@ -80,8 +96,8 @@ public void test_serialize_invalid_uuris() throws UnknownHostException { @DisplayName("Test serialize and deserialize IPv4 UUris") public void test_serialize_ipv4_uri() throws UnknownHostException { UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("192.168.1.100")); - UEntity use = UEntity.fromId(1, (short)2); - UResource uResource = UResource.fromId((short)3); + UEntity use = UEntity.microFormat((short)2, 1); + UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); byte[] bytes = UriSerializer.MICRO.serialize(uri); @@ -93,8 +109,8 @@ public void test_serialize_ipv4_uri() throws UnknownHostException { @DisplayName("Test serialize and deserialize IPv6 UUris") public void test_serialize_ipv6_uri() throws UnknownHostException { UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UEntity use = UEntity.fromId(1, (short)2); - UResource uResource = UResource.fromId((short)3); + UEntity use = UEntity.microFormat((short)2, 1); + UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); byte[] bytes = UriSerializer.MICRO.serialize(uri); @@ -106,8 +122,8 @@ public void test_serialize_ipv6_uri() throws UnknownHostException { @DisplayName("Test deserialize with missing information") public void test_deserialize_with_missing_information() throws UnknownHostException { UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UEntity use = UEntity.fromId(1, (short)2); - UResource uResource = UResource.fromId((short)3); + UEntity use = UEntity.microFormat((short)2, 1); + UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); byte[] bytes = UriSerializer.MICRO.serialize(uri); diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriPartValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java similarity index 99% rename from src/test/java/org/eclipse/uprotocol/uri/validator/UriPartValidatorTest.java rename to src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java index 6027df8a..ff78b4a3 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UriPartValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java @@ -36,7 +36,7 @@ import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; -class UriPartValidatorTest { +class UUriValidatorTest { @Test @DisplayName("Test validate blank uri") @@ -80,7 +80,7 @@ public void test_validate_with_malformed_uri() { @Test @DisplayName("Test validate with blank UEntity Name") public void test_validate_with_blank_uentity_name_uri() { - final UUri uri = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpc("echo")); + final UUri uri = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpcRequest("echo")); final UStatus status = UriValidator.validate(uri); assertFalse(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index 68ba687a..4471f335 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -58,7 +58,7 @@ public void testToString() { final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.LOW) - .withSink(new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.empty())) + .withSink(new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.empty())) .withTtl(1000) .withToken("someToken") .withPermissionLevel(1) @@ -67,8 +67,8 @@ public void testToString() { .build(); assertEquals(String.format("UAttributes{id=%s, type=RESPONSE, priority=LOW, ttl=1000, token='someToken', " + "sink=UriPart{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + - "uEntity=UEntity{name='body.access', version='latest', id='null'}, " + - "uResource=UResource{name='', instance='null', message='null', id='null'}}, " + + "uEntity=UEntity{name='body.access', version=null, id=null, markedResolved=false}, " + + "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}, " + "plevel=1, commstatus=5, reqid=%s}", id,requestId), uAttributes.toString()); @@ -79,7 +79,7 @@ public void testToString() { public void testCreatingUattributes() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.empty()); + final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.empty()); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -129,7 +129,7 @@ public void test_basic_uattribues_only_required_values() { @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC request") public void test_create_uattributes_builder_for_basic_rpc_request() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes uAttributes = UAttributes.forRpcRequest(id, sink) .withToken("someToken") .withTtl(10000) @@ -147,7 +147,7 @@ public void test_create_uattributes_builder_for_basic_rpc_request() { @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC request with values") public void test_create_uattributes_builder_for_basic_rpc_request_with_values() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UAttributes uAttributes = UAttributes.forRpcRequest(id, UAuthority.local(), UEntity.fromName("body.access"), "ExecuteWindowCommand") + final UAttributes uAttributes = UAttributes.forRpcRequest(id, UAuthority.local(), UEntity.longFormat("body.access"), "ExecuteWindowCommand") .withToken("someToken") .withTtl(10000) .build(); @@ -165,7 +165,7 @@ public void test_create_uattributes_builder_for_basic_rpc_request_with_values() public void test_create_uattributes_builder_for_basic_rpc_response() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = UAttributes.forRpcResponse(id, sink, requestId) .withToken("someToken") @@ -186,7 +186,7 @@ public void test_create_uattributes_builder_for_basic_rpc_response_with_values() final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = UAttributes.forRpcResponse(id, UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), requestId) + UEntity.longFormat("petapp.ultifi.gm.com",1), requestId) .withToken("someToken") .withTtl(10000) .build(); @@ -332,7 +332,7 @@ public void test_create_uattributes_with_null_request_id() { @DisplayName("Test is this UAttributes configured for an RPC request payload") public void test_is_uattributes_configured_for_rpc_request_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -346,7 +346,7 @@ public void test_scenarios_for_uattributes_not_configured_for_rpc_request_payloa final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final String vin = "someVin"; final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", vin)), - UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .build(); @@ -365,7 +365,7 @@ public void test_is_uattributes_configured_for_rpc_response_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); final UUri sink = new UUri(UAuthority.longRemote("azure", "bo.ultifi.gm.com"), - new UEntity("petapp.ultifi.gm.com",1), UResource.empty()); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.empty()); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -380,7 +380,7 @@ public void test_scenarios_for_uattributes_not_configured_for_rpc_response_paylo final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); final UUri sink = new UUri(UAuthority.longRemote("azure", "bo.ultifi.gm.com"), - new UEntity("petapp.ultifi.gm.com",1), UResource.empty()); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.empty()); final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withReqId(requestId) diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index abb5a8fb..5190bc1f 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -94,7 +94,7 @@ public void test_validate_uAttributes_for_publish_message_payload_all_values() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW) .withTtl(1000) - .withSink(new UUri(UAuthority.local(), UEntity.fromName("body.access"), new UResource("door", "front_left", "Door"))) + .withSink(new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.longFormat("door", "front_left", "Door"))) .withPermissionLevel(2) .withCommStatus(3) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) @@ -218,7 +218,7 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_reques @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request") public void test_validate_uAttributes_for_rpc_request_message_payload() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -235,7 +235,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload() { @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with all values") public void test_validate_uAttributes_for_rpc_request_message_payload_all_values() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -255,7 +255,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_all_values @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -272,7 +272,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid type") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_type() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -289,7 +289,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ty @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid priority") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_priority() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, null) .withSink(sink) @@ -306,7 +306,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_pr @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with missing time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_missing_ttl() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -322,7 +322,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_missing_tt @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ttl() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -351,7 +351,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_missing_si @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid sink") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_sink() { - final UUri sink = new UUri(UAuthority.local(), UEntity.fromName("body.access"), UResource.forRpc("ExecuteWindowCommand")); + final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -368,7 +368,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_si @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid permission level") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_permission_level() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -386,7 +386,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_pe @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid communication status") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_communication_status() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -404,7 +404,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_co @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid request id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_request_id() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -424,7 +424,7 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_re @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response") public void test_validate_uAttributes_for_rpc_response_message_payload() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -441,7 +441,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload() { @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with all values") public void test_validate_uAttributes_for_rpc_response_message_payload_all_values() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -460,7 +460,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_all_value @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_id() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -477,7 +477,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_i @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid type") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_type() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -494,7 +494,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_t @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid priority") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_priority() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, null) .withSink(sink) @@ -511,7 +511,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_p @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid time to live") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_ttl() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -541,7 +541,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_missing_s @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid sink") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_sink() { - final UUri sink = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpc("ExecuteWindowCommand")); + final UUri sink = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -558,7 +558,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_s @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid permission level") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_permission_level() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -576,7 +576,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_p @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid communication status") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_communication_status() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -594,7 +594,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_c @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with missing request id") public void test_validate_uAttributes_for_rpc_response_message_payload_missing_request_id() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -610,7 +610,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_missing_r @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid request id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_request_id() { final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - new UEntity("petapp.ultifi.gm.com",1), UResource.fromNameWithInstance("rpc", "response")); + UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UUID reqid = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) From d9d8f2b92e6d7d008c07929bffe4a19a731d2445 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 19 Sep 2023 09:29:24 -0400 Subject: [PATCH 36/52] Rename UriParts to UriFormat Also make UUri implement this interface (cuz it should). --- .../uprotocol/uri/datamodel/UAuthority.java | 2 +- .../uprotocol/uri/datamodel/UEntity.java | 2 +- .../uprotocol/uri/datamodel/UResource.java | 12 ++--- .../eclipse/uprotocol/uri/datamodel/UUri.java | 6 ++- .../{UriPart.java => UriFormat.java} | 6 +-- .../uri/datamodel/UResourceTest.java | 44 +++++++++---------- .../uprotocol/uri/datamodel/UUriTest.java | 12 ++--- 7 files changed, 44 insertions(+), 40 deletions(-) rename src/main/java/org/eclipse/uprotocol/uri/datamodel/{UriPart.java => UriFormat.java} (85%) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index e36d6ba7..814ba505 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -31,7 +31,7 @@ * Devices will be grouped together into realms of Zone of Authority.
* An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ -public class UAuthority implements UriPart { +public class UAuthority implements UriFormat { private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 0be910c2..375ebd31 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -31,7 +31,7 @@ * A uE that publishes events is a Service role.
* A uE that consumes events is an Application role. */ -public class UEntity implements UriPart { +public class UEntity implements UriFormat { private static final UEntity EMPTY = new UEntity("", null, null, false); private final String name; // uE Name diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index df644e62..226d84b9 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -31,7 +31,7 @@ * An UResource is something that can be manipulated/controlled/exposed by a service. Resources are unique when prepended with UAuthority that represents the device and * UEntity that represents the service. */ -public class UResource implements UriPart { +public class UResource implements UriFormat { private static final UResource EMPTY = new UResource("", null,null, null, false); @@ -71,24 +71,24 @@ private UResource(String name, String instance, String message, Short id, boolea * @param message The Message type matches the protobuf service IDL message name that defines structured data types. * A message is a data structure type used to define data that is passed in events and rpc methods. * @param id The numeric representation of this uResource. - * @return Returns a UResource that has all the information that is needed to serialise into a long UUri or a micro UUri. + * @return Returns a UResource that has all the information that is needed to serialize into a long UUri or a micro UUri. */ - public static UResource resolved(String name, String instance, String message, Short id) { + public static UResource resolvedFormat(String name, String instance, String message, Short id) { boolean resolved = name != null && !name.isEmpty() && instance != null && !instance.isEmpty() && id != null; return new UResource(name, instance, message, id, resolved); } /** - * Build a UResource that can be serialised into a long UUri. Mostly used for publishing messages. + * Build a UResource that can be serialized into a long UUri. Mostly used for publishing messages. * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @return Returns a UResource that can be serialised into a long UUri. + * @return Returns a UResource that can be serialized into a long UUri. */ public static UResource longFormat(String name) { return new UResource(name, null, null, null, false); } /** - * Build a UResource that can be serialised into a long UUri. Mostly used for publishing messages. + * Build a UResource that can be serialized into a long UUri. Mostly used for publishing messages. * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. * @param instance An instance of a resource such as front_left. * @param message The Message type matches the protobuf service IDL message name that defines structured data types. diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index d6b2df70..12301ab2 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -36,7 +36,7 @@ * * */ -public class UUri { +public class UUri implements UriFormat { private static final UUri EMPTY = new UUri(UAuthority.empty(), UEntity.empty(), UResource.empty()); private final UAuthority uAuthority; @@ -89,6 +89,7 @@ public static UUri empty() { * Indicates that this URI is an empty container and has no valuable information in building uProtocol sinks or sources. * @return Returns true if this URI is an empty container and has no valuable information in building uProtocol sinks or sources. */ + @Override public boolean isEmpty() { return uAuthority.isLocal() && uEntity().isEmpty() && uResource.isEmpty(); @@ -100,6 +101,7 @@ public boolean isEmpty() { * @return Returns true if URI contains both names and numeric representations of the names inside its belly. * Meaning that this UUri can be serialised to long or micro formats. */ + @Override public boolean isResolved() { return uAuthority.isResolved() && uEntity.isResolved() && uResource.isResolved(); } @@ -108,6 +110,7 @@ public boolean isResolved() { * Determines if this UUri can be serialised into a long form UUri. * @return Returns true if this UUri can be serialised into a long form UUri. */ + @Override public boolean isLongForm() { return uAuthority.isLongForm() && uEntity.isLongForm() && uResource.isLongForm(); } @@ -116,6 +119,7 @@ public boolean isLongForm() { * Determines if this UUri can be serialised into a micro form UUri. * @return Returns true if this UUri can be serialised into a micro form UUri. */ + @Override public boolean isMicroForm() { return uAuthority.isMicroForm() && uEntity.isMicroForm() && uResource.isMicroForm(); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java similarity index 85% rename from src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java rename to src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java index bea3d222..da76d101 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriPart.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java @@ -1,10 +1,10 @@ package org.eclipse.uprotocol.uri.datamodel; /** - * Basic building blocks for all data models that are part of a uProtocol URI. - * The interface defines APIs that MUST be implemented in all Uri uProtocol parts. + * Interface used to provide hints as to how the Uri part or Uri itself is formated meaning does it contain + * long format, micro format or both (resolved) information. */ -public interface UriPart { +public interface UriFormat { /** * Supporting empty Uri parts enables avoiding null values in the data model, and can indicate the absence of a Uri Part. diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index fda1da77..3ba4fbed 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -151,7 +151,7 @@ public void test_create_rpc_response_using_response_method() { @Test @DisplayName("Test creating an UResource with valid id") public void test_create_UResource_with_valid_id() { - UResource uResource = UResource.resolved("door", "front_left", "Door", (short)5); + UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", (short)5); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); @@ -165,7 +165,7 @@ public void test_create_UResource_with_valid_id() { @Test @DisplayName("Test creating an UResource with invalid id") public void test_create_UResource_with_invalid_id() { - UResource uResource = UResource.resolved("door", "front_left", "Door", null); + UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", null); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); @@ -203,7 +203,7 @@ public void test_create_response_UResource_by_calling_fromId() { @Test @DisplayName("Test creating a response UResource passing name, instance, and id") public void test_create_response_UResource_passing_name_instance_and_id() { - UResource uResource = UResource.resolved("rpc", "response", null, (short)0); + UResource uResource = UResource.resolvedFormat("rpc", "response", null, (short)0); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isPresent()); assertEquals("response", uResource.instance().get()); @@ -216,7 +216,7 @@ public void test_create_response_UResource_passing_name_instance_and_id() { @Test @DisplayName("Test creating a request UResource passing name, instance, and id") public void test_create_request_UResource_passing_name_instance_and_id() { - UResource uResource = UResource.resolved("rpc", null, null, (short)0); + UResource uResource = UResource.resolvedFormat("rpc", null, null, (short)0); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); @@ -228,7 +228,7 @@ public void test_create_request_UResource_passing_name_instance_and_id() { @Test @DisplayName("Test isResolved with resolved UResources") public void test_isResolved_with_resolved_UResources() { - UResource uResource = UResource.resolved("door", "front_left", "Door", (short)5); + UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", (short)5); assertTrue(uResource.isResolved()); UResource uResource2 = UResource.forRpcResponse(); assertTrue(uResource2.isResolved()); @@ -239,7 +239,7 @@ public void test_isResolved_with_resolved_UResources() { @Test @DisplayName("Test isResolved and isLongForm with unresolved UResources") public void test_isResolved_with_unresolved_UResources() { - UResource uResource = UResource.resolved("door", "front_left", "Door", null); + UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", null); assertFalse(uResource.isResolved()); assertTrue(uResource.isLongForm()); UResource uResource2 = UResource.longFormat("door"); @@ -261,37 +261,37 @@ public void test_isResolved_with_unresolved_UResources() { @Test @DisplayName("Test resolved API with all possible combinations of the APIs passed valid and invalid") public void test_resolved_API_with_all_possible_combinations_of_the_APIs_passed_valid_and_invalid() { - UResource uResource = UResource.resolved("door", "front_left", "Door", (short)5); + UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", (short)5); assertTrue(uResource.isResolved()); - UResource uResource2 = UResource.resolved("door", "front_left", "Door", null); + UResource uResource2 = UResource.resolvedFormat("door", "front_left", "Door", null); assertFalse(uResource2.isResolved()); - UResource uResource3 = UResource.resolved("door", "front_left", null, (short)5); + UResource uResource3 = UResource.resolvedFormat("door", "front_left", null, (short)5); assertTrue(uResource3.isResolved()); - UResource uResource4 = UResource.resolved("door", "front_left", null, null); + UResource uResource4 = UResource.resolvedFormat("door", "front_left", null, null); assertFalse(uResource4.isResolved()); - UResource uResource5 = UResource.resolved("door", null, "Door", (short)5); + UResource uResource5 = UResource.resolvedFormat("door", null, "Door", (short)5); assertFalse(uResource5.isResolved()); - UResource uResource6 = UResource.resolved("door", null, "Door", null); + UResource uResource6 = UResource.resolvedFormat("door", null, "Door", null); assertFalse(uResource6.isResolved()); - UResource uResource7 = UResource.resolved("door", null, null, (short)5); + UResource uResource7 = UResource.resolvedFormat("door", null, null, (short)5); assertFalse(uResource7.isResolved()); - UResource uResource8 = UResource.resolved("door", null, null, null); + UResource uResource8 = UResource.resolvedFormat("door", null, null, null); assertFalse(uResource8.isResolved()); - UResource uResource9 = UResource.resolved(null, "front_left", "Door", (short)5); + UResource uResource9 = UResource.resolvedFormat(null, "front_left", "Door", (short)5); assertFalse(uResource9.isResolved()); - UResource uResource10 = UResource.resolved(null, "front_left", "Door", null); + UResource uResource10 = UResource.resolvedFormat(null, "front_left", "Door", null); assertFalse(uResource10.isResolved()); - UResource uResource11 = UResource.resolved(null, "front_left", null, (short)5); + UResource uResource11 = UResource.resolvedFormat(null, "front_left", null, (short)5); assertFalse(uResource11.isResolved()); - UResource uResource12 = UResource.resolved(null, "front_left", null, null); + UResource uResource12 = UResource.resolvedFormat(null, "front_left", null, null); assertFalse(uResource12.isResolved()); - UResource uResource13 = UResource.resolved(null, null, "Door", (short)5); + UResource uResource13 = UResource.resolvedFormat(null, null, "Door", (short)5); assertFalse(uResource13.isResolved()); - UResource uResource14 = UResource.resolved(null, null, "Door", null); + UResource uResource14 = UResource.resolvedFormat(null, null, "Door", null); assertFalse(uResource14.isResolved()); - UResource uResource15 = UResource.resolved(null, null, null, (short)5); + UResource uResource15 = UResource.resolvedFormat(null, null, null, (short)5); assertFalse(uResource15.isResolved()); - UResource uResource16 = UResource.resolved(null, null, null, null); + UResource uResource16 = UResource.resolvedFormat(null, null, null, null); assertFalse(uResource16.isResolved()); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 014cfc0b..9e8bda8a 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -179,11 +179,11 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri2.isResolved()); assertTrue(uri2.isLongForm()); - UUri uri3 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); + UUri uri3 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri3.isResolved()); assertTrue(uri3.isLongForm()); - UUri uri4 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); + UUri uri4 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri4.isResolved()); assertTrue(uri4.isLongForm()); @@ -195,11 +195,11 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri5.isResolved()); assertTrue(uri5.isLongForm()); - UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); + UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri6.isResolved()); assertTrue(uri6.isLongForm()); - UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); + UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri7.isResolved()); assertTrue(uri7.isLongForm()); @@ -208,11 +208,11 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri8.isResolved()); assertTrue(uri8.isLongForm()); - UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); + UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri9.isResolved()); assertTrue(uri9.isLongForm()); - UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolved("Raise", "Salary", "Bonus", (short)1)); + UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri10.isResolved()); assertTrue(uri10.isLongForm()); From 29b3bc6586a548726a4032caba657fb7f15ab1b8 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 19 Sep 2023 16:41:10 -0400 Subject: [PATCH 37/52] Added deserialize(String,byte[]) API Added an api to support building a resolved UUri with passed serialized Long and Micro data --- .../eclipse/uprotocol/uri/datamodel/UUri.java | 18 +++--- .../uprotocol/uri/datamodel/UriFormat.java | 2 +- .../uri/serializer/UriSerializer.java | 55 ++++++++++++++-- .../uri/serializer/LongUriSerializerTest.java | 62 +++++++++++++++++++ 4 files changed, 123 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 12301ab2..3cd3be78 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -30,7 +30,7 @@ * Where software is deployed, what the service is called along with a version and the resources in the service. * Defining a common URI for the system allows applications and/or services to publish and discover each other * as well as maintain a database/repository of microservices in the various vehicles.
- * Example for long format serialisation: + * Example for long format serialization: *
  *     //<device>.<domain>/<service>/<version>/<resource>#<message>
  * 
@@ -79,7 +79,7 @@ public static UUri rpcResponse(UAuthority uAuthority, UEntity uEntity) { /** * Static factory method for creating an empty uri, to avoid working with null
- * @return Returns an empty ultify uri to avoid working with null. + * @return Returns an empty uri to avoid working with null. */ public static UUri empty() { return EMPTY; @@ -97,9 +97,9 @@ public boolean isEmpty() { /** * Returns true if URI contains both names and numeric representations of the names inside its belly. - * Meaning that this UUri can be serialised to long or micro formats. + * Meaning that this UUri can be serialized to long or micro formats. * @return Returns true if URI contains both names and numeric representations of the names inside its belly. - * Meaning that this UUri can be serialised to long or micro formats. + * Meaning that this UUri can be serialized to long or micro formats. */ @Override public boolean isResolved() { @@ -107,8 +107,8 @@ public boolean isResolved() { } /** - * Determines if this UUri can be serialised into a long form UUri. - * @return Returns true if this UUri can be serialised into a long form UUri. + * Determines if this UUri can be serialized into a long form UUri. + * @return Returns true if this UUri can be serialized into a long form UUri. */ @Override public boolean isLongForm() { @@ -116,8 +116,8 @@ public boolean isLongForm() { } /** - * Determines if this UUri can be serialised into a micro form UUri. - * @return Returns true if this UUri can be serialised into a micro form UUri. + * Determines if this UUri can be serialized into a micro form UUri. + * @return Returns true if this UUri can be serialized into a micro form UUri. */ @Override public boolean isMicroForm() { @@ -125,7 +125,7 @@ public boolean isMicroForm() { } /** - * @return Returns the Authority represents the deployment location of a specific Software Entity. + * @return Returns the Authority represents the deployment location of a specific Software Entity. */ public UAuthority uAuthority() { return uAuthority; diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java index da76d101..9e337750 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java @@ -1,7 +1,7 @@ package org.eclipse.uprotocol.uri.datamodel; /** - * Interface used to provide hints as to how the Uri part or Uri itself is formated meaning does it contain + * Interface used to provide hints as to how the Uri part or Uri itself is formatted meaning does it contain * long format, micro format or both (resolved) information. */ public interface UriFormat { diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index c36d8d6a..0124e6d2 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -21,6 +21,9 @@ package org.eclipse.uprotocol.uri.serializer; +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; /** @@ -37,23 +40,67 @@ public interface UriSerializer { * @param uri serialized UUri * @return deserialized UUri object */ - public UUri deserialize(T uri); + UUri deserialize(T uri); /** * Serialize from a UUri to the format * @param uri UUri object to be serialized to the format T * @return serialized UUri */ - public T serialize(UUri uri); + T serialize(UUri uri); /** * Long form serializer */ - public static LongUriSerializer LONG = new LongUriSerializer(); + static LongUriSerializer LONG = new LongUriSerializer(); /** * Micro form serializer */ - public static MicroUriSerializer MICRO = new MicroUriSerializer(); + static MicroUriSerializer MICRO = new MicroUriSerializer(); + + + /** + * Deserialize from a both a long and micro into a resolved UUri + */ + default UUri deserialize(String longUri, byte[] microUri) { + + if (longUri == null || longUri.isEmpty() || microUri == null || microUri.length == 0) { + return UUri.empty(); + } + + UUri longUUri = LONG.deserialize(longUri); + UUri microUUri = MICRO.deserialize(microUri); + + + // Check if the UUris built are valid + if (!longUUri.isLongForm() || !microUUri.isMicroForm()) { + return UUri.empty(); + } + + // Both authority types should match (both local or both remote) + if (longUUri.uAuthority().isLocal() != microUUri.uAuthority().isLocal()) { + return UUri.empty(); + } + + + UAuthority uAuthority = longUUri.uAuthority().isLocal() ? UAuthority.local() : + UAuthority.resolvedRemote( + longUUri.uAuthority().device().get(), + longUUri.uAuthority().domain().orElse(null), + microUUri.uAuthority().address().get()); + + UEntity uEntity = UEntity.resolvedFormat( + longUUri.uEntity().name(), longUUri.uEntity().version().orElse(null), + microUUri.uEntity().id().get()); + + UResource uResource = UResource.resolvedFormat( + longUUri.uResource().name(), + longUUri.uResource().instance().orElse(null), + longUUri.uResource().message().orElse(null), + microUUri.uResource().id().get()); + + return new UUri(uAuthority, uEntity, uResource); + } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index 8cae5c2a..ee83fc57 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -6,6 +6,9 @@ import static org.junit.jupiter.api.Assertions.*; +import java.net.InetAddress; +import java.net.UnknownHostException; + import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; @@ -895,4 +898,63 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { assertEquals(uri2, UriSerializer.LONG.serialize(Uri)); } + @Test + @DisplayName("Test deserializer a long and micro uri passing garbage") + void test_deserialize_long_and_micro_passing_garbage() { + UUri uri = UriSerializer.LONG.deserialize(null, null); + assertTrue(uri.isEmpty()); + + UUri uri1 = UriSerializer.LONG.deserialize(null, new byte[0]); + assertTrue(uri1.isEmpty()); + + UUri uri2 = UriSerializer.LONG.deserialize("", null); + assertTrue(uri2.isEmpty()); + + UUri uri3 = UriSerializer.LONG.deserialize("", new byte[0]); + assertTrue(uri3.isEmpty()); + } + + @Test + @DisplayName("Test deserializer a long and micro uri passing UAuthority of different types (local vs remote)") + void test_deserialize_long_and_micro_passing_UAuthority_that_doesnt_match() { + String longUUri = "//vcu.vin/body.access//door.front_left#Door"; + byte[] microUUri = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri = UriSerializer.LONG.deserialize(longUUri, microUUri); + assertTrue(uri.isEmpty()); + + String longUUri1 = "/body.access//door.front_left#Door"; + byte[] microUUri1 = new byte[] {0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri1 = UriSerializer.LONG.deserialize(longUUri1, microUUri1); + assertTrue(uri1.isEmpty()); + } + + @Test + @DisplayName("Test deserializer a long and micro uri passing invalid values") + void test_deserialize_long_and_micro_passing_invalid_values() { + String goodLongUUri = "/body.access//door.front_left#Door"; + byte[] goodMicroUUri = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + String badLongUUri = "///"; + byte[] badMicroUUri = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0}; + UUri uri = UriSerializer.LONG.deserialize(goodLongUUri, goodMicroUUri); + assertFalse(uri.isEmpty()); + + UUri uri2 = UriSerializer.LONG.deserialize(goodLongUUri, badMicroUUri); + assertTrue(uri2.isEmpty()); + UUri uri3 = UriSerializer.LONG.deserialize(badLongUUri, goodMicroUUri); + assertTrue(uri3.isEmpty()); + UUri uri4 = UriSerializer.LONG.deserialize(badLongUUri, badMicroUUri); + assertTrue(uri4.isEmpty()); + } + + @Test + @DisplayName("Test deserializer a long and micro uri passing valid values") + void test_deserialize_long_and_micro_passing_valid_values() throws UnknownHostException { + UUri uri = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), + UEntity.resolvedFormat("hartley", 1, (short)5), + UResource.resolvedFormat("raise", "salary", "Pay", (short)2)); + String longUUri = UriSerializer.LONG.serialize(uri); + byte[] microUUri = UriSerializer.MICRO.serialize(uri); + UUri uri2 = UriSerializer.LONG.deserialize(longUUri, microUUri); + assertEquals(uri, uri2); + } } From d33db748d26f0930c92d95475fccd888d4aaa590 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 19 Sep 2023 20:23:06 -0400 Subject: [PATCH 38/52] Further test coverage --- .../uprotocol/uri/datamodel/UEntityTest.java | 7 +++ .../uri/datamodel/UResourceTest.java | 44 ++++++++++++++++++- .../uprotocol/uri/datamodel/UUriTest.java | 33 ++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 1e2eef0a..952a72c5 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -225,5 +225,12 @@ public void test_create_use_with_valid_id_and_version() { assertFalse(use5.isLongForm()); assertFalse(use5.isResolved()); assertFalse(use5.isMicroForm()); + + try { + UEntity use6 = UEntity.resolvedFormat(null, null, null); + } catch (NullPointerException e) { + assertTrue(e.getMessage().contains(" Software Entity must have a name")); + } + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 3ba4fbed..7c14fb43 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -41,6 +41,7 @@ public void testToString() { UResource uResource = UResource.longFormat("door", "front_left", "Door"); String expected = "UResource{name='door', instance='front_left', message='Door', id=null, markedResolved=false}"; assertEquals(expected, uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -52,6 +53,7 @@ public void test_create_Resource() { assertEquals("front_left", uResource.instance().get()); assertTrue(uResource.message().isPresent()); assertEquals("Door", uResource.message().get()); + assertFalse(uResource.isEmpty()); } @Test @@ -61,11 +63,13 @@ public void test_create_Resource_with_no_instance_and_no_message() { assertEquals("door", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); + assertFalse(uResource.isEmpty()); UResource uResource2 = UResource.longFormat("door", null, null); assertEquals("door", uResource2.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); + assertFalse(uResource.isEmpty()); } @Test @@ -75,6 +79,7 @@ public void test_create_Resource_with_no_instance_and_no_message_using_fromName( assertEquals("door", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); + assertFalse(uResource.isEmpty()); } @Test @@ -85,6 +90,7 @@ public void test_create_Resource_with_no_message_using_fromName() { assertTrue(uResource.instance().isPresent()); assertEquals("front_left", uResource.instance().get()); assertTrue(uResource.message().isEmpty()); + assertFalse(uResource.isEmpty()); } @Test @@ -95,6 +101,7 @@ public void test_create_Resource_for_rpc_commands() { assertTrue(uResource.instance().isPresent()); assertEquals("UpdateDoor", uResource.instance().get()); assertTrue(uResource.isRPCMethod()); + assertFalse(uResource.isEmpty()); } @Test @@ -109,6 +116,7 @@ public void test_Resource_represents_an_rpc_method_call() { public void test_Resource_represents_a_resource_and_not_an_rpc_method_call() { UResource uResource = UResource.longFormat("door"); assertFalse(uResource.isRPCMethod()); + assertFalse(uResource.isEmpty()); } @@ -120,6 +128,7 @@ public void test_create_empty_using_empty() { assertTrue(uResource.name().isEmpty()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.isEmpty()); } @Test @@ -160,6 +169,7 @@ public void test_create_UResource_with_valid_id() { assertTrue(uResource.id().isPresent()); assertEquals((int)5, (int)uResource.id().get()); assertEquals("UResource{name='door', instance='front_left', message='Door', id=5, markedResolved=true}", uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -173,6 +183,7 @@ public void test_create_UResource_with_invalid_id() { assertEquals("Door", uResource.message().get()); assertFalse(uResource.id().isPresent()); assertEquals("UResource{name='door', instance='front_left', message='Door', id=null, markedResolved=false}", uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -185,6 +196,7 @@ public void test_create_UResource_by_calling_fromId_static_method() { assertTrue(uResource.id().isPresent()); assertEquals((int)5, (int)uResource.id().get()); assertEquals("UResource{name='', instance='null', message='null', id=5, markedResolved=false}", uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -198,6 +210,7 @@ public void test_create_response_UResource_by_calling_fromId() { assertTrue(uResource.id().isPresent()); assertEquals((int)0, (int)uResource.id().get()); assertEquals("UResource{name='rpc', instance='response', message='null', id=0, markedResolved=true}", uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -211,6 +224,7 @@ public void test_create_response_UResource_passing_name_instance_and_id() { assertTrue(uResource.id().isPresent()); assertEquals((int)0, (int)uResource.id().get()); assertEquals("UResource{name='rpc', instance='response', message='null', id=0, markedResolved=true}", uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -223,6 +237,7 @@ public void test_create_request_UResource_passing_name_instance_and_id() { assertTrue(uResource.id().isPresent()); assertEquals((int)0, (int)uResource.id().get()); assertEquals("UResource{name='rpc', instance='null', message='null', id=0, markedResolved=false}", uResource.toString()); + assertFalse(uResource.isEmpty()); } @Test @@ -318,6 +333,33 @@ public void test_forRpcRequest_with_null_and_valid_short_value() { assertFalse(uResource2.isResolved()); assertFalse(uResource2.isLongForm()); assertTrue(uResource2.isRPCMethod()); - //assertFalse(uResource.isMicroForm()); + + UResource uResource3 = UResource.forRpcRequest(null, null); + assertEquals("rpc", uResource3.name()); + assertFalse(uResource3.instance().isPresent()); + assertTrue(uResource3.message().isEmpty()); + assertFalse(uResource3.id().isPresent()); + assertFalse(uResource3.isResolved()); + assertFalse(uResource3.isLongForm()); + assertTrue(uResource3.isRPCMethod()); + + UResource uResource4 = UResource.forRpcRequest("", null); + assertEquals("rpc", uResource4.name()); + assertFalse(uResource4.instance().isPresent()); + assertTrue(uResource4.message().isEmpty()); + assertFalse(uResource4.id().isPresent()); + assertFalse(uResource4.isResolved()); + assertFalse(uResource4.isLongForm()); + assertTrue(uResource4.isRPCMethod()); + + UResource uResource5 = UResource.forRpcRequest(null, (short)2); + assertEquals("rpc", uResource5.name()); + assertFalse(uResource5.instance().isPresent()); + assertTrue(uResource5.message().isEmpty()); + assertTrue(uResource5.id().isPresent()); + assertFalse(uResource5.isResolved()); + assertFalse(uResource5.isLongForm()); + assertTrue(uResource5.isRPCMethod()); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 9e8bda8a..020547b0 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -174,51 +174,84 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri.isResolved()); assertFalse(uri.isLongForm()); + assertFalse(uri.isMicroForm()); UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); assertFalse(uri2.isResolved()); assertTrue(uri2.isLongForm()); + assertFalse(uri2.isMicroForm()); UUri uri3 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri3.isResolved()); assertTrue(uri3.isLongForm()); + assertFalse(uri3.isMicroForm()); UUri uri4 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri4.isResolved()); assertTrue(uri4.isLongForm()); + assertFalse(uri3.isMicroForm()); UUri uri11 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.forRpcRequest("Raise")); assertFalse(uri11.isResolved()); assertTrue(uri11.isLongForm()); + assertFalse(uri11.isMicroForm()); UUri uri5 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); assertFalse(uri5.isResolved()); assertTrue(uri5.isLongForm()); + assertFalse(uri5.isMicroForm()); UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri6.isResolved()); assertTrue(uri6.isLongForm()); + assertFalse(uri6.isMicroForm()); UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri7.isResolved()); assertTrue(uri7.isLongForm()); + assertFalse(uri7.isMicroForm()); + + UUri uri14 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.resolvedFormat("Hartley", 1, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); + assertFalse(uri14.isResolved()); + assertTrue(uri14.isLongForm()); + assertFalse(uri14.isMicroForm()); UUri uri8 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); assertFalse(uri8.isResolved()); assertTrue(uri8.isLongForm()); + assertFalse(uri8.isMicroForm()); UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertFalse(uri9.isResolved()); assertTrue(uri9.isLongForm()); + assertFalse(uri9.isMicroForm()); UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); assertTrue(uri10.isResolved()); assertTrue(uri10.isLongForm()); + assertTrue(uri10.isMicroForm()); UUri uri12 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.microFormat((short)2)); assertFalse(uri12.isResolved()); assertFalse(uri12.isLongForm()); + assertTrue(uri12.isMicroForm()); + + UUri uri16 = new UUri(UAuthority.local(), UEntity.microFormat((short)2, 1), UResource.microFormat((short)2)); + assertFalse(uri16.isResolved()); + assertFalse(uri16.isLongForm()); + assertTrue(uri16.isMicroForm()); + + + UUri uri17 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.microFormat((short)2, 1), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); + assertFalse(uri17.isResolved()); + assertFalse(uri17.isLongForm()); + assertTrue(uri17.isMicroForm()); + + UUri uri18 = new UUri(UAuthority.local(), UEntity.microFormat((short)2, 1), UResource.microFormat((short)2)); + assertFalse(uri18.isResolved()); + assertFalse(uri18.isLongForm()); + assertTrue(uri18.isMicroForm()); } From d2d1e0298af0bfaa9df035afa8674858cfe433ea Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 19 Sep 2023 21:00:22 -0400 Subject: [PATCH 39/52] more test coverage --- .../uprotocol/uri/datamodel/UAuthorityTest.java | 15 +++++++++++++++ .../uprotocol/uri/datamodel/UResourceTest.java | 17 ++++++++++++++++- .../uprotocol/uri/datamodel/UUriTest.java | 5 +++++ .../uri/serializer/LongUriSerializerTest.java | 16 +++++++++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index c8661c11..13ab43e0 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -205,12 +205,27 @@ public void test_isResolved_with_resolved_uAuthority() throws UnknownHostExcepti UAuthority local = UAuthority.local(); UAuthority remote = UAuthority.resolvedRemote("192.168.1.100", null, InetAddress.getByName("192.168.1.100")); UAuthority remote1 = UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")); + UAuthority remote2 = UAuthority.resolvedRemote("", null, InetAddress.getByName("192.168.1.100")); + UAuthority remote3 = UAuthority.resolvedRemote("vcu", "vin", null); + UAuthority remote4 = UAuthority.resolvedRemote(null, null, null); assertTrue(local.isResolved()); assertTrue(local.isLongForm()); + assertTrue(local.isEmpty()); assertTrue(remote.isResolved()); assertTrue(remote.isLongForm()); + assertFalse(remote.isEmpty()); assertTrue(remote1.isResolved()); assertTrue(remote1.isLongForm()); + assertFalse(remote1.isEmpty()); + assertFalse(remote2.isResolved()); + assertFalse(remote2.isLongForm()); + assertFalse(remote2.isEmpty()); + assertFalse(remote3.isResolved()); + assertTrue(remote3.isLongForm()); + assertFalse(remote3.isEmpty()); + assertFalse(remote4.isResolved()); + assertTrue(remote4.isLongForm()); + assertTrue(remote4.isEmpty()); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 7c14fb43..3f2a31dc 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -308,6 +308,12 @@ public void test_resolved_API_with_all_possible_combinations_of_the_APIs_passed_ assertFalse(uResource15.isResolved()); UResource uResource16 = UResource.resolvedFormat(null, null, null, null); assertFalse(uResource16.isResolved()); + + + UResource uResource17 = UResource.resolvedFormat("", "front_left", "Door", (short)5); + assertFalse(uResource17.isResolved()); + UResource uResource18 = UResource.resolvedFormat("door", "", "Door", null); + assertFalse(uResource18.isResolved()); } @Test @@ -352,7 +358,16 @@ public void test_forRpcRequest_with_null_and_valid_short_value() { assertFalse(uResource4.isLongForm()); assertTrue(uResource4.isRPCMethod()); - UResource uResource5 = UResource.forRpcRequest(null, (short)2); + UResource uResource6 = UResource.forRpcRequest("hello", null); + assertEquals("rpc", uResource6.name()); + assertTrue(uResource6.instance().isPresent()); + assertTrue(uResource6.message().isEmpty()); + assertFalse(uResource6.id().isPresent()); + assertFalse(uResource6.isResolved()); + assertTrue(uResource6.isLongForm()); + assertTrue(uResource6.isRPCMethod()); + + UResource uResource5 = UResource.forRpcRequest("", (short)2); assertEquals("rpc", uResource5.name()); assertFalse(uResource5.instance().isPresent()); assertTrue(uResource5.message().isEmpty()); diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 020547b0..64df6824 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -237,6 +237,11 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { assertFalse(uri12.isLongForm()); assertTrue(uri12.isMicroForm()); + UUri uri19 = new UUri(UAuthority.microRemote(InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.microFormat((short)2)); + assertFalse(uri19.isResolved()); + assertFalse(uri19.isLongForm()); + assertTrue(uri19.isMicroForm()); + UUri uri16 = new UUri(UAuthority.local(), UEntity.microFormat((short)2, 1), UResource.microFormat((short)2)); assertFalse(uri16.isResolved()); assertFalse(uri16.isLongForm()); diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index ee83fc57..3afc1862 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -937,13 +937,27 @@ void test_deserialize_long_and_micro_passing_invalid_values() { byte[] badMicroUUri = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0}; UUri uri = UriSerializer.LONG.deserialize(goodLongUUri, goodMicroUUri); assertFalse(uri.isEmpty()); - UUri uri2 = UriSerializer.LONG.deserialize(goodLongUUri, badMicroUUri); assertTrue(uri2.isEmpty()); UUri uri3 = UriSerializer.LONG.deserialize(badLongUUri, goodMicroUUri); assertTrue(uri3.isEmpty()); UUri uri4 = UriSerializer.LONG.deserialize(badLongUUri, badMicroUUri); assertTrue(uri4.isEmpty()); + UUri uri5 = UriSerializer.LONG.deserialize("", goodMicroUUri); + assertTrue(uri5.isEmpty()); + UUri uri6 = UriSerializer.LONG.deserialize("", badMicroUUri); + assertTrue(uri6.isEmpty()); + UUri uri7 = UriSerializer.LONG.deserialize(null, goodMicroUUri); + assertTrue(uri7.isEmpty()); + UUri uri8 = UriSerializer.LONG.deserialize(null, badMicroUUri); + assertTrue(uri8.isEmpty()); + + + UUri uri9 = UriSerializer.LONG.deserialize(goodLongUUri, null); + assertTrue(uri9.isEmpty()); + UUri uri10 = UriSerializer.LONG.deserialize(goodLongUUri, new byte[0]); + assertTrue(uri10.isEmpty()); + } @Test From dbf1a07b35ff886a94105dc09d3888995e9c2ee6 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 19 Sep 2023 21:06:47 -0400 Subject: [PATCH 40/52] Fix coverage in UUIDValidator --- .../uprotocol/uuid/validator/UuidValidatorTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java index 81c35bb0..c5ed1d79 100644 --- a/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java @@ -86,4 +86,15 @@ void test_invalid_validator_uuid() { assertEquals(Code.INVALID_ARGUMENT_VALUE, statusv8.getCode()); assertEquals("Invalid Version 6", statusv8.getMessage()); } + + @Test + @DisplayName("Test using invalid validator when passed an invalid UUID type") + void test_invalid_validator_uuid_type() { + final UUID uuid = new UUID(0, 0); + UuidValidator validator = UuidValidator.getValidator(uuid); + final Status status = validator.validate(uuid); + + assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); + assertEquals("Invalid UUID Format", status.getMessage()); + } } From 4a1786daad00cf40c65d7ef7838b064a253cb20e Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Wed, 20 Sep 2023 20:35:44 +0300 Subject: [PATCH 41/52] working on UUri --- .../uprotocol/uri/datamodel/UAuthority.java | 100 ++-- .../uprotocol/uri/datamodel/UEntity.java | 35 +- .../uprotocol/uri/datamodel/UResource.java | 22 +- .../eclipse/uprotocol/uri/datamodel/UUri.java | 4 +- .../uri/datamodel/UAuthorityTest.java | 328 ++++++----- .../uprotocol/uri/datamodel/UEntityTest.java | 296 +++++----- .../uri/datamodel/UResourceTest.java | 535 ++++++++++-------- .../uprotocol/uri/datamodel/UUriTest.java | 81 ++- 8 files changed, 823 insertions(+), 578 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java index 814ba505..8081b4a6 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java @@ -26,10 +26,10 @@ import java.util.Optional; /** - * Data representation of an Authority.
An Authority consists of a device and a domain.
- * Device and domain names are used as part of the URI for device and service discovery.
+ * An Authority represents the deployment location of a specific Software Entity. + * Data representation of an Authority.
An Authority consists of a device, a domain and a micro version in the form of an IP Address.
+ * Device and domain names are used as part of the URI for device and service discovery. Optimized micro versions of the UUri will use the IP Address.
* Devices will be grouped together into realms of Zone of Authority.
- * An Authority represents the deployment location of a specific Software Entity in the Ultiverse. */ public class UAuthority implements UriFormat { private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); @@ -49,26 +49,29 @@ public class UAuthority implements UriFormat { /** * An UAuthority starting with // is a remote configuration of a URI, and we mark the uAuthority implicitly as remote. + * This is never exposed externally and is used internally to indicate remote or local deployments. */ private final boolean markedRemote; /** - * The device IP address. + * The device IP address. Represents the micro version of a UAuthority. */ private final InetAddress address; /** * Indicates that this UAuthority has already been resolved. + * A resolved UAuthority means that it has all the information needed to be serialised in the long format or the micro format of a UUri. */ private final boolean markedResolved; /** * Constructor for building a UAuthority. - * @param device The device a software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). - * @param domain The domain a software entity is deployed on, such as vehicle or backoffice. - * @param address The device IP address. + * @param device The device a software entity is deployed on, such as the VCU, CCU or cloud provider. + * @param domain The domain a software entity is deployed on, such as vehicle or Cloud (PaaS). + * @param address The device IP address of the device. * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. - * @param markedResolved Indicates that this uResource was populated with intent of having all data. + * @param markedResolved Indicates that this uAuthority has all the information needed to be serialised + * in the long format or the micro format of a UUri. */ private UAuthority(String device, String domain, InetAddress address, boolean markedRemote, boolean markedResolved) { this.device = device == null ? null : device.toLowerCase(); @@ -79,31 +82,34 @@ private UAuthority(String device, String domain, InetAddress address, boolean ma } /** - * Static factory method for creating a local authority.
+ * Static factory method for creating a local uAuthority.
* A local uri does not contain an authority and looks like this: *
 :<service>/<version>/<resource>#<Message> 
- * @return Returns a local uAuthority that has no domain, device, or ip address information. + * @return Returns a local uAuthority that has no domain, device, or ip address information, indicating to uProtocol + * that the uAuthority part in the UUri is relative to the sender/receiver deployment environment. */ public static UAuthority local() { return EMPTY; } /** - * Static factory method for creating a remote authority using the long representation.
- * An uri with a long representation of uAUthority can be serialized as follows: + * Static factory method for creating a remote authority supporting the long serialization information representation of a UUri.
+ * Building a UAuthority with this method will create an unresolved uAuthority that can only be serialised in long UUri format. + * An uri with a long representation of uAUthority can be serialised as follows: *
 //<device>.<domain>/<service>/<version>/<resource>#<Message> 
- * @param device The device a software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). - * @param domain The domain a software entity is deployed on, such as vehicle or backoffice. Vehicle Domain name MUST be that of the vehicle VIN. - * @return Returns a uAuthority that contains the device and the domain and can be serialized in long UUri format. + * @param device The device a software entity is deployed on, such as the VCU, CCU or cloud provider. + * @param domain The domain a software entity is deployed on, such as vehicle or Cloud (PaaS). Vehicle Domain name MUST be that of the vehicle VIN. + * @return Returns a uAuthority that contains the device and the domain and can only be serialized in long UUri format. */ public static UAuthority longRemote(String device, String domain) { return new UAuthority(device, domain, null, true, false); } /** - * Static factory method for creating a remote authority using the micro representation.
+ * Static factory method for creating a remote authority supporting the micro serialization information representation of a UUri.
+ * Building a UAuthority with this method will create an unresolved uAuthority that can only be serialised in micro UUri format. * @param address The ip address of the device a software entity is deployed on. - * @return Returns a uAuthority that contains only the internet address of the device, and can be serialized in micro UUri format. + * @return Returns a uAuthority that contains only the internet address of the device, and can only be serialized in micro UUri format. */ public static UAuthority microRemote(InetAddress address) { return new UAuthority(null, null, address, true, false); @@ -111,6 +117,8 @@ public static UAuthority microRemote(InetAddress address) { /** * Static factory method for creating a remote authority that is completely resolved with name, device and ip address of the device.
+ * Building a UAuthority with this method will enable serialisation in both UUri formats, long UUri format and micro UUri format. + * Note that in the case of missing data, this will not fail, but simply create a UAuthority that is not resolved. * @param device The device name for long serialization of UUri. * @param domain The domain name for long serialization of UUri. * @param address the IP address for the device, for micro serialization of UUri. @@ -123,6 +131,7 @@ public static UAuthority resolvedRemote(String device, String domain, InetAddres /** * Static factory method for creating an empty uAuthority, to avoid working with null
+ * Empty uAuthority is still serializable in both long and micro UUri formats, and will be as local to the current deployment environment. * @return Returns an empty authority that has no domain, device, or device ip address information. */ public static UAuthority empty() { @@ -130,27 +139,15 @@ public static UAuthority empty() { } /** - * @return Returns true if this uAuthority is remote, meaning it contains information for long UUri or micro UUri. - */ - public boolean isRemote() { - return isMarkedRemote(); - } - - /** - * @return returns true if this uAuthority is local, meaning does not contain a device/domain for long UUri or information for micro UUri. - */ - public boolean isLocal() { - return domain().isEmpty() && device().isEmpty() && address().isEmpty(); - } - - /** - * @return Returns the device a software entity is deployed on, such as the VCU, CCU or Cloud (PaaS). + * Accessing an optional device of the uAuthority. + * @return Returns the device a software entity is deployed on, such as the VCU, CCU or cloud provider. */ public Optional device() { return device == null || device.isBlank() ? Optional.empty() : Optional.of(device); } /** + * Accessing an optional domain of the uAuthority. * @return Returns the domain a software entity is deployed on, such as vehicle or backoffice. */ public Optional domain() { @@ -158,6 +155,7 @@ public Optional domain() { } /** + * Accessing an optional IP address configuration of the uAuthority. * @return Returns the device IP address. */ public Optional address() { @@ -165,15 +163,33 @@ public Optional address() { } /** - * @return Returns the explicitly configured remote deployment. + * Support for determining if this uAuthority is defined for a local deployment. + * @return returns true if this uAuthority is local, meaning does not contain a device/domain for long UUri or information for micro UUri. + */ + public boolean isLocal() { + return isEmpty() && !isMarkedRemote(); + } + + /** + * Support for determining if this uAuthority defines a deployment that is defined as remote. + * @return Returns true if this uAuthority is remote, meaning it contains information for serialising a long UUri or a micro UUri. + */ + public boolean isRemote() { + return isMarkedRemote(); + } + + /** + * Support for determining if this uAuthority was configured to be remote. + * @return Returns true if this uAuthority is explicitly configured remote deployment. */ public boolean isMarkedRemote() { return markedRemote; } /** - * Returns true if the UAuthority was tagged as resolved meaning the name values and the ip address of the device are present. - * @return Returns true if UAuthority is resolved with all the information. + * Indicates that this UAuthority has already been resolved. + * A resolved UAuthority means that it has all the information needed to be serialised in the long format or the micro format of a UUri. + * @return Returns true if this UAuthority is resolved with all the information needed to be serialised in the long format or the micro format of a UUri. */ @Override public boolean isResolved() { @@ -181,8 +197,8 @@ public boolean isResolved() { } /** - * Check if the UAuthority can be used to serialize a long UUri. - * @return Returns true if the UAuthority can be used to serialize a long UUri. + * Determine if the UAuthority can be used to serialize a UUri in long format. + * @return Returns true if the UAuthority can be used to serialize a UUri in long format. */ @Override public boolean isLongForm() { @@ -190,8 +206,8 @@ public boolean isLongForm() { } /** - * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. - * @return Returns true if the Uri part can be serialized into micro form. + * Determine if the UAuthority can be used to serialize a UUri in micro format. + * @return Returns true if the uAuthority can be serialized a UUri in micro format. */ @Override public boolean isMicroForm() { @@ -200,7 +216,7 @@ public boolean isMicroForm() { @Override public boolean isEmpty() { - return isLocal(); + return domain().isEmpty() && device().isEmpty() && address().isEmpty(); } @Override @@ -222,9 +238,9 @@ public String toString() { return "UAuthority{" + "device='" + device + '\'' + ", domain='" + domain + '\'' + - ", address='" + address + '\'' + ", markedRemote=" + markedRemote + + ", address=" + address + + ", markedResolved=" + markedResolved + '}'; } - } diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 375ebd31..94c5198d 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -26,6 +26,7 @@ /** * Data representation of an Software Entity - uE
+ * Software entities are distinguished by using a unique name or a unique id along with the specific version of the software. * An Software Entity is a piece of software deployed somewhere on a uDevice.
* The Software Entity is used in the source and sink parts of communicating software.
* A uE that publishes events is a Service role.
@@ -43,7 +44,7 @@ public class UEntity implements UriFormat { * Build a Software Entity that represents a communicating piece of software. * @param name The name of the software such as petapp or body.access. * @param version The software version. If not supplied, the latest version of the service will be used. - * @param id A numeric identifier for the software entity. + * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. * @param markedResolved Indicates that this uResource was populated with intent of having all data. */ private UEntity(String name, Integer version, Short id, boolean markedResolved) { @@ -54,13 +55,21 @@ private UEntity(String name, Integer version, Short id, boolean markedResolved) this.markedResolved = markedResolved; } + /** + * Create a complete UEntity with all the information so that it can be used in long form UUri serialisation and micro form UUri serialisation. + * In the case of missing elements such as name or id, the UEntity will not be marked as resolvable and will not be usable in serialisation formats. + * @param name The name of the software such as petapp or body.access. + * @param version The software version. If not supplied, the latest version of the service will be used. + * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. + * @return Returns a complete UEntity with all the information so that it can be used in long form UUri serialisation and micro form UUri serialisation. + */ public static UEntity resolvedFormat(String name, Integer version, Short id) { boolean resolved = name != null && !name.isEmpty() && id != null; return new UEntity(name, version, id, resolved); } /** - * Static factory method for creating a uE using the software entity name, that can be used to serialize long UUris. + * Static factory method for creating a uE using the software entity name, that can be used in long form UUri serialisation. * @param name The software entity name, such as petapp or body.access. * @return Returns an UEntity with the name where the version is the latest version of the service and can only be serialized * to long UUri format. @@ -70,7 +79,7 @@ public static UEntity longFormat(String name) { } /** - * Static factory method for creating a uE using the software entity name, that can be used to serialize long UUris. + * Static factory method for creating a uE using the software entity name, that can be used long form UUri serialisation. * @param name The software entity name, such as petapp or body.access. * @param version The software entity version. * @return Returns an UEntity with the name and the version of the service and can only be serialized @@ -82,9 +91,9 @@ public static UEntity longFormat(String name, Integer version) { /** * Static factory method for creating a uE using the software entity identification number, that can be used to serialize micro UUris. - * @param id The software entity name, such as petapp or body.access. + * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. * @return Returns an UEntity with the name where the version is the latest version of the service and can only be serialized - * to long UUri format. + * to long micro UUri format. */ public static UEntity microFormat(Short id) { return new UEntity("", null, id, false); @@ -92,26 +101,26 @@ public static UEntity microFormat(Short id) { /** * Static factory method for creating a uE using the software entity identification number, that can be used to serialize micro UUris. - * @param id The software entity name, such as petapp or body.access. + * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. * @param version The software entity version. * @return Returns an UEntity with the name and the version of the service and can only be serialized - * to long UUri format. + * to micro UUri format. */ public static UEntity microFormat(Short id, Integer version) { return new UEntity("", version, id, false); } /** - * Static factory method for creating an empty software entity, to avoid working with null
- * @return Returns an empty software entity that has a blank name and no version information. + * Static factory method for creating an empty software entity, to avoid working with null
+ * @return Returns an empty software entity that has a blank name, no unique id and no version information. */ public static UEntity empty() { return EMPTY; } /** - * Indicates that this USE is an empty container and has no valuable information in building uProtocol sinks or sources. - * @return Returns true if this USE is an empty container and has no valuable information in building uProtocol sinks or sources. + * Indicates that this software entity is an empty container and has no valuable information in building uProtocol sinks or sources. + * @return Returns true if this software entity is an empty container and has no valuable information in building uProtocol sinks or sources. */ @Override public boolean isEmpty() { @@ -134,12 +143,12 @@ public boolean isResolved() { */ @Override public boolean isLongForm() { - return !name().isEmpty(); + return !name().isBlank(); } /** * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. - * @return Returns true if the Uri part can be serialized into micro form. + * @return Returns true if the Uri part can be serialized into micro form, meaning is has at least a unique numeric identifier. */ @Override public boolean isMicroForm() { diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java index 226d84b9..4652c990 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java @@ -25,8 +25,8 @@ import java.util.Optional; /** - * An service API - defined in the {@link UEntity} - has Resources and Methods. Both of these are represented by the UResource class.
- * An Resource represents a resource from a Service such as "door" and an optional specific instance such as "front_left". In addition, it can optionally contain + * A service API - defined in the {@link UEntity} - has Resources and Methods. Both of these are represented by the UResource class.
+ * A uResource represents a resource from a Service such as "door" and an optional specific instance such as "front_left". In addition, it can optionally contain * the name of the resource Message type, such as "Door". The Message type matches the protobuf service IDL that defines structured data types.
* An UResource is something that can be manipulated/controlled/exposed by a service. Resources are unique when prepended with UAuthority that represents the device and * UEntity that represents the service. @@ -65,7 +65,7 @@ private UResource(String name, String instance, String message, Short id, boolea } /** - * Build a UResource that has serialization information. + * Build a UResource that has all elements resolved and can be serialized in a long UUri or a micro UUri. * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. * @param instance An instance of a resource such as front_left. * @param message The Message type matches the protobuf service IDL message name that defines structured data types. @@ -74,7 +74,7 @@ private UResource(String name, String instance, String message, Short id, boolea * @return Returns a UResource that has all the information that is needed to serialize into a long UUri or a micro UUri. */ public static UResource resolvedFormat(String name, String instance, String message, Short id) { - boolean resolved = name != null && !name.isEmpty() && instance != null && !instance.isEmpty() && id != null; + boolean resolved = name != null && !name.isBlank() && id != null; return new UResource(name, instance, message, id, resolved); } @@ -133,7 +133,7 @@ public static UResource forRpcRequest(Short methodId) { * @return Returns a UResource used for an RPC request that could be serialised in long and micro format. */ public static UResource forRpcRequest(String methodName, Short methodId) { - boolean resolved = methodName != null && !methodName.isEmpty() && methodId != null; + boolean resolved = methodName != null && !methodName.isBlank() && methodId != null; return new UResource("rpc", methodName, null, methodId, resolved); } @@ -146,10 +146,11 @@ public static UResource forRpcResponse() { } /** - * @return Returns true if this resource specifies an RPC method call. + * @return Returns true if this resource specifies an RPC method call or RPC response. */ public boolean isRPCMethod() { - return name.equals("rpc"); + return (name.equals("rpc") && instance().isPresent()) || + (name.equals("rpc") && id().isPresent()); } /** @@ -165,7 +166,7 @@ public static UResource empty() { * @return Returns true if this resource is an empty container and has no valuable information in building uProtocol URI. */ public boolean isEmpty() { - return name.isBlank() && instance().isEmpty() && message().isEmpty() && id().isEmpty(); + return (name.isBlank() || "rpc".equals(name)) && instance().isEmpty() && message().isEmpty() && id().isEmpty(); } /** @@ -217,7 +218,10 @@ public boolean isResolved() { */ @Override public boolean isLongForm() { - return !name().isEmpty() && instance().isPresent(); + if (name.equals("rpc")) { + return instance().isPresent(); + } + return !name().isBlank(); } /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index 3cd3be78..d8aa175f 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -112,7 +112,9 @@ public boolean isResolved() { */ @Override public boolean isLongForm() { - return uAuthority.isLongForm() && uEntity.isLongForm() && uResource.isLongForm(); + return uAuthority.isLongForm() && + (uEntity.isLongForm() || uEntity.isEmpty()) && + (uResource.isLongForm() || uResource().isEmpty()); } /** diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java index 13ab43e0..e855ce76 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java @@ -25,11 +25,10 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - import java.net.Inet6Address; import java.net.InetAddress; -import java.net.UnknownHostException; + +import static org.junit.jupiter.api.Assertions.*; class UAuthorityTest { @@ -44,14 +43,26 @@ public void testHashCodeEquals() { public void testToString() { UAuthority uAuthority = UAuthority.longRemote("VCU", "my_VIN"); String sRemote = uAuthority.toString(); - String expectedRemote = "UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}"; + String expectedRemote = "UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}"; assertEquals(expectedRemote, sRemote); + final InetAddress address = createAddressForMicroDeviceForTest(); + UAuthority microRemote = UAuthority.microRemote(address); + String sMicroRemote = microRemote.toString(); + String expectedMicroRemote = "UAuthority{device='null', domain='null', markedRemote=true, address=localhost/127.0.0.1, markedResolved=false}"; + assertEquals(expectedMicroRemote, sMicroRemote); + + UAuthority resolvedRemote = UAuthority.resolvedRemote("VCU", "MY_VIN", address); + assertEquals("UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=localhost/127.0.0.1, markedResolved=true}", resolvedRemote.toString()); + UAuthority local = UAuthority.local(); String sLocal = local.toString(); - String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=false}"; + String expectedLocal = "UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}"; assertEquals(expectedLocal, sLocal); + UAuthority empty = UAuthority.empty(); + assertEquals("UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}", empty.toString()); + } @Test @@ -59,188 +70,239 @@ public void testToString() { public void testToString_case_sensitivity() { UAuthority uAuthority = UAuthority.longRemote("vcU", "my_VIN"); String sRemote = uAuthority.toString(); - String expectedRemote = "UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}"; + String expectedRemote = "UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}"; assertEquals(expectedRemote, sRemote); + } - UAuthority local = UAuthority.local(); - String sLocal = local.toString(); - String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=false}"; - assertEquals(expectedLocal, sLocal); - + @Test + @DisplayName("Test create a empty uAuthority") + public void test_create_empty_uAuthority() { + UAuthority uAuthority = UAuthority.empty(); + assertTrue(uAuthority.device().isEmpty()); + assertTrue(uAuthority.domain().isEmpty()); + assertTrue(uAuthority.address().isEmpty()); + assertTrue(uAuthority.isLocal()); + assertFalse(uAuthority.isRemote()); + assertFalse(uAuthority.isMarkedRemote()); + assertTrue(uAuthority.isResolved()); + assertTrue(uAuthority.isEmpty()); + assertTrue(uAuthority.isMicroForm()); + assertTrue(uAuthority.isLongForm()); } @Test - @DisplayName("Test a local uAuthority") - public void test_local_uAuthority() { + @DisplayName("Test create a local uAuthority") + public void test_create_local_uAuthority() { UAuthority uAuthority = UAuthority.local(); assertTrue(uAuthority.device().isEmpty()); assertTrue(uAuthority.domain().isEmpty()); + assertTrue(uAuthority.address().isEmpty()); assertTrue(uAuthority.isLocal()); + assertFalse(uAuthority.isRemote()); assertFalse(uAuthority.isMarkedRemote()); + assertTrue(uAuthority.isResolved()); + assertTrue(uAuthority.isEmpty()); + assertTrue(uAuthority.isMicroForm()); + assertTrue(uAuthority.isLongForm()); } @Test - @DisplayName("Test a local uAuthority when one part is empty") - public void test_local_uAuthority_one_part_empty() { - UAuthority uAuthority = UAuthority.longRemote("", "My_VIN"); + @DisplayName("Test create a remote uAuthority that supports long UUris") + public void test_create_remote_uAuthority_that_supports_long_uuri() { + String device = "vcu"; + String domain = "myvin"; + UAuthority uAuthority = UAuthority.longRemote(device, domain); + assertEquals(device, uAuthority.device().orElse("")); + assertEquals(domain, uAuthority.domain().orElse("")); + assertTrue(uAuthority.address().isEmpty()); assertFalse(uAuthority.isLocal()); - UAuthority uAuthority2 = UAuthority.longRemote("VCU", ""); - assertFalse(uAuthority2.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertTrue(uAuthority.isLongForm()); } @Test - @DisplayName("Test a microRemote uAuthority") - public void test_remote_uAuthority() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "my_VIN"); - assertTrue(uAuthority.device().isPresent()); - assertEquals("vcu", uAuthority.device().get()); - assertTrue(uAuthority.domain().isPresent()); - assertEquals("my_vin", uAuthority.domain().get()); + @DisplayName("Test create a remote uAuthority that supports long UUris null device") + public void test_create_remote_uAuthority_that_supports_long_uuri_null_device() { + String domain = "myvin"; + UAuthority uAuthority = UAuthority.longRemote(null, domain); + assertTrue(uAuthority.device().isEmpty()); + assertEquals(domain, uAuthority.domain().orElse("")); + assertTrue(uAuthority.address().isEmpty()); + assertFalse(uAuthority.isLocal()); assertTrue(uAuthority.isRemote()); assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } @Test - @DisplayName("Test a microRemote uAuthority with case sensitivity") - public void test_remote_uAuthority_case_sensitive() { - UAuthority uAuthority = UAuthority.longRemote("VCu", "my_VIN"); - assertTrue(uAuthority.device().isPresent()); - assertEquals("vcu", uAuthority.device().get()); - assertTrue(uAuthority.domain().isPresent()); - assertEquals("my_vin", uAuthority.domain().get()); + @DisplayName("Test create a remote uAuthority that supports long UUris missing device") + public void test_create_remote_uAuthority_that_supports_long_uuri_missing_device() { + String device = " "; + String domain = "myvin"; + UAuthority uAuthority = UAuthority.longRemote(device, domain); + assertTrue(uAuthority.device().isEmpty()); + assertEquals(domain, uAuthority.domain().orElse("")); + assertTrue(uAuthority.address().isEmpty()); + assertFalse(uAuthority.isLocal()); assertTrue(uAuthority.isRemote()); assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } @Test - @DisplayName("Test a blank microRemote uAuthority is actually local") - public void test_blank_remote_uAuthority_is_local() { - UAuthority uAuthority = UAuthority.longRemote(" ", " "); - assertTrue(uAuthority.device().isEmpty()); + @DisplayName("Test create a remote uAuthority that supports long UUris null domain") + public void test_create_remote_uAuthority_that_supports_long_uuri_null_domain() { + String device = "vcu"; + UAuthority uAuthority = UAuthority.longRemote(device, null); + assertEquals(device, uAuthority.device().orElse("")); assertTrue(uAuthority.domain().isEmpty()); - assertTrue(uAuthority.isLocal()); + assertTrue(uAuthority.address().isEmpty()); + assertFalse(uAuthority.isLocal()); assertTrue(uAuthority.isRemote()); assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertTrue(uAuthority.isLongForm()); } @Test - @DisplayName("Make sure the empty() works") - public void testEmpty() { - UAuthority uAuthority = UAuthority.empty(); + @DisplayName("Test create a remote uAuthority that supports micro UUris") + public void test_create_remote_uAuthority_that_supports_micro_uuri() { + final InetAddress address = createAddressForMicroDeviceForTest(); + UAuthority uAuthority = UAuthority.microRemote(address); assertTrue(uAuthority.device().isEmpty()); assertTrue(uAuthority.domain().isEmpty()); + assertEquals(address, uAuthority.address().orElse(null)); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertTrue(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } @Test - @DisplayName("Make sure the isLocal() works") - public void test_isLocal() { - UAuthority local = UAuthority.local(); - assertTrue(local.isLocal()); - assertFalse(local.isRemote()); - assertFalse(local.isMarkedRemote()); + @DisplayName("Test create a remote uAuthority that supports micro UUris with null address") + public void test_create_remote_uAuthority_that_supports_micro_uuri_with_null_address() { + UAuthority uAuthority = UAuthority.microRemote(null); + assertTrue(uAuthority.device().isEmpty()); + assertTrue(uAuthority.domain().isEmpty()); + assertTrue(uAuthority.address().isEmpty()); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertTrue(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } @Test - @DisplayName("Make sure the isRemote() works") - public void test_isRemote() { - UAuthority remote = UAuthority.longRemote("VCU", "my_VIN"); - assertFalse(remote.isLocal()); - assertTrue(remote.isRemote()); - assertTrue(remote.isMarkedRemote()); + @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris") + public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri() { + String device = "vcu"; + String domain = "myvin"; + final InetAddress address = createAddressForMicroDeviceForTest(); + UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, address); + assertEquals(device, uAuthority.device().orElse("")); + assertEquals(domain, uAuthority.domain().orElse("")); + assertEquals(address, uAuthority.address().orElse(null)); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertTrue(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertTrue(uAuthority.isMicroForm()); + assertTrue(uAuthority.isLongForm()); } - - + @Test - @DisplayName("Test creating uAuthority with invalid ip address") - public void test_create_uAuthority_with_invalid_ip_address() { - UAuthority remote = UAuthority.microRemote((InetAddress)null); - String expectedLocal = "UAuthority{device='null', domain='null', address='null', markedRemote=true}"; - assertEquals(expectedLocal, remote.toString()); - assertFalse(remote.address().isPresent()); + @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with null device") + public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_null_device() { + String domain = "myvin"; + final InetAddress address = createAddressForMicroDeviceForTest(); + UAuthority uAuthority = UAuthority.resolvedRemote(null, domain, address); + assertTrue(uAuthority.device().isEmpty()); + assertEquals(domain, uAuthority.domain().orElse("")); + assertEquals(address, uAuthority.address().orElse(null)); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertTrue(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } - @Test - @DisplayName("Test creating uAuthority with valid ip address") - public void test_create_uAuthority_with_valid_ip_address() { - InetAddress address = Inet6Address.getLoopbackAddress(); - - UAuthority remote = UAuthority.microRemote(address); - String expectedLocal = "UAuthority{device='null', domain='null', address='localhost/127.0.0.1', markedRemote=true}"; - InetAddress address2 = remote.address().get(); - assertTrue(remote.address().isPresent()); - assertEquals(address, address2); - assertEquals(expectedLocal, remote.toString()); + @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with blank device") + public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_blank_device() { + String device = " "; + String domain = "myvin"; + final InetAddress address = createAddressForMicroDeviceForTest(); + UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, address); + assertTrue(uAuthority.device().isEmpty()); + assertEquals(domain, uAuthority.domain().orElse("")); + assertEquals(address, uAuthority.address().orElse(null)); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertTrue(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } @Test - @DisplayName("Test creating uAuthority with valid ipv6 address") - public void test_create_uAuthority_with_valid_ipv6_address() { - String ipv6Address = "2001:db8:85a3:0:0:8a2e:370:7334"; - InetAddress address = null; - try { - address = InetAddress.getByName(ipv6Address); - } - catch (UnknownHostException e) { - e.printStackTrace(); - } - - UAuthority remote = UAuthority.microRemote(address); - String expectedLocal = "UAuthority{device='null', domain='null', address='/2001:db8:85a3:0:0:8a2e:370:7334', markedRemote=true}"; - assertEquals(expectedLocal, remote.toString()); + @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with missing address") + public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_missing_address() { + String device = "vcu"; + String domain = "myvin"; + UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, null); + assertEquals(device, uAuthority.device().orElse("")); + assertEquals(domain, uAuthority.domain().orElse("")); + assertTrue(uAuthority.address().isEmpty()); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertFalse(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertTrue(uAuthority.isLongForm()); } @Test - @DisplayName("Test creating uAuthority with valid ipv4 address in the device name") - public void test_create_uAuthority_with_valid_ipv4_address_in_device_name() { - UAuthority remote = UAuthority.longRemote("192.168.1.100", null); - String expectedLocal = "UAuthority{device='192.168.1.100', domain='null', address='null', markedRemote=true}"; - assertEquals(expectedLocal, remote.toString()); + @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with missing data") + public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_missing_all_data() { + String device = ""; + String domain = ""; + UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, null); + assertTrue(uAuthority.device().isEmpty()); + assertTrue(uAuthority.domain().isEmpty()); + assertTrue(uAuthority.address().isEmpty()); + assertFalse(uAuthority.isLocal()); + assertTrue(uAuthority.isRemote()); + assertTrue(uAuthority.isMarkedRemote()); + assertFalse(uAuthority.isResolved()); + assertTrue(uAuthority.isEmpty()); + assertFalse(uAuthority.isMicroForm()); + assertFalse(uAuthority.isLongForm()); } - - @Test - @DisplayName("Test isResolved() and isLongForm() with a resolved uAuthority") - public void test_isResolved_with_resolved_uAuthority() throws UnknownHostException { - UAuthority local = UAuthority.local(); - UAuthority remote = UAuthority.resolvedRemote("192.168.1.100", null, InetAddress.getByName("192.168.1.100")); - UAuthority remote1 = UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")); - UAuthority remote2 = UAuthority.resolvedRemote("", null, InetAddress.getByName("192.168.1.100")); - UAuthority remote3 = UAuthority.resolvedRemote("vcu", "vin", null); - UAuthority remote4 = UAuthority.resolvedRemote(null, null, null); - assertTrue(local.isResolved()); - assertTrue(local.isLongForm()); - assertTrue(local.isEmpty()); - assertTrue(remote.isResolved()); - assertTrue(remote.isLongForm()); - assertFalse(remote.isEmpty()); - assertTrue(remote1.isResolved()); - assertTrue(remote1.isLongForm()); - assertFalse(remote1.isEmpty()); - assertFalse(remote2.isResolved()); - assertFalse(remote2.isLongForm()); - assertFalse(remote2.isEmpty()); - assertFalse(remote3.isResolved()); - assertTrue(remote3.isLongForm()); - assertFalse(remote3.isEmpty()); - assertFalse(remote4.isResolved()); - assertTrue(remote4.isLongForm()); - assertTrue(remote4.isEmpty()); - } - - - @Test - @DisplayName("Test isResolved() and isLongForm() with a unresolved uAuthority") - public void test_isResolved_with_unresolved_uAuthority() throws UnknownHostException { - UAuthority remote = UAuthority.longRemote("vcu", "vin"); - UAuthority remote1 = UAuthority.microRemote(InetAddress.getByName("192.168.1.100")); - UAuthority remote2 = UAuthority.empty(); - assertFalse(remote.isResolved()); - assertTrue(remote.isLongForm()); - assertFalse(remote1.isResolved()); - assertFalse(remote1.isLongForm()); - assertTrue(remote2.isResolved()); - assertTrue(remote2.isLongForm()); + private InetAddress createAddressForMicroDeviceForTest() { + return Inet6Address.getLoopbackAddress(); } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 952a72c5..90c26747 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals; + class UEntityTest { @Test @@ -52,39 +53,82 @@ public void testToString() { } @Test - @DisplayName("Test creating a complete USE") - public void test_create_use() { - UEntity use = UEntity.longFormat("body.access", 1); + @DisplayName("Test creating a software entity for use in long format UUri with name") + public void test_create_use_for_use_with_long_format_uuri_with_name() { + UEntity use = UEntity.longFormat("body.access"); assertEquals("body.access", use.name()); - assertTrue(use.version().isPresent()); - assertEquals(1, use.version().get()); + assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertTrue(use.isLongForm()); + assertFalse(use.isMicroForm()); } @Test - @DisplayName("Test creating a complete USE with a null name, expect exception") - public void test_create_use_null_name() { - Exception exception = assertThrows(NullPointerException.class, () -> UEntity.longFormat(null, 1)); + @DisplayName("Test creating a software entity for use in long format UUri with name that is blank") + public void test_create_use_for_use_with_long_format_uuri_with_name_that_is_blank() { + UEntity use = UEntity.longFormat(" "); + assertEquals(" ", use.name()); + assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertTrue(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertFalse(use.isMicroForm()); + } + + @Test + @DisplayName("Test creating a software entity for use in long format UUri with name that is null, expect exception") + public void test_create_use_for_use_with_long_format_uuri_with_name_that_is_null() { + Exception exception = assertThrows(NullPointerException.class, () -> UEntity.longFormat(null)); assertTrue(exception.getMessage().contains(" Software Entity must have a name")); } @Test - @DisplayName("Test creating a USE with no version") - public void test_create_use_with_no_version() { - UEntity use = UEntity.longFormat("body.access", null); + @DisplayName("Test creating a software entity for use in long format UUri with name and version") + public void test_create_use_for_use_with_long_format_uuri_with_name_and_version() { + UEntity use = UEntity.longFormat("body.access", 1); assertEquals("body.access", use.name()); - assertTrue(use.version().isEmpty()); + assertEquals(1, use.version().orElse(-1)); + assertTrue(use.id().isEmpty()); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertTrue(use.isLongForm()); + assertFalse(use.isMicroForm()); + } - UEntity use2 = UEntity.longFormat("body.access", null); - assertEquals("body.access", use2.name()); - assertTrue(use2.version().isEmpty()); + @Test + @DisplayName("Test creating a software entity for use in long format UUri with blank name and null version") + public void test_create_use_for_use_with_long_format_uuri_with_blank_name_and_no_version() { + UEntity use = UEntity.longFormat("", null); + assertEquals("", use.name()); + assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertTrue(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertFalse(use.isMicroForm()); } @Test - @DisplayName("Test creating a USE using the longFormat static method") - public void test_create_use_with_no_version_using_longFormat() { - UEntity use = UEntity.longFormat("body.access"); + @DisplayName("Test creating a software entity for use in long format UUri with blank name and null version") + public void test_create_use_for_use_with_long_format_uuri_with_name_and_no_version() { + UEntity use = UEntity.longFormat("body.access", null); assertEquals("body.access", use.name()); assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertTrue(use.isLongForm()); + assertFalse(use.isMicroForm()); + } + + @Test + @DisplayName("Test creating a software entity for use in long format UUri with name and version, null name, expect exception") + public void test_create_use_for_use_with_long_format_uuri_with_name_and_version_null_name() { + Exception exception = assertThrows(NullPointerException.class, () -> UEntity.longFormat(null, 1)); + assertTrue(exception.getMessage().contains(" Software Entity must have a name")); } @Test @@ -93,144 +137,140 @@ public void test_create_empty_using_empty() { UEntity use = UEntity.empty(); assertTrue(use.name().isEmpty()); assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertTrue(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertFalse(use.isMicroForm()); } @Test - @DisplayName("Test the isEmpty static method") - public void test_is_empty() { - UEntity use = UEntity.empty(); - assertTrue(use.isEmpty()); - - UEntity use2 = UEntity.longFormat("", null); - assertTrue(use2.isEmpty()); - - UEntity use3 = UEntity.longFormat("", 1); - assertFalse(use3.isEmpty()); - - UEntity use4 = UEntity.longFormat("petapp", null); - assertFalse(use4.isEmpty()); + @DisplayName("Test creating a software entity for use in micro format UUri with id") + public void test_create_use_for_use_with_micro_format_uuri_with_id() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.microFormat(id); + assertTrue(use.name().isBlank()); + assertTrue(use.version().isEmpty()); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertTrue(use.isMicroForm()); } @Test - @DisplayName("Test creating UEntity with id") - public void test_create_use_with_id() { - UEntity use = UEntity.resolvedFormat("body.access", 1, (short)0); - assertEquals("body.access", use.name()); - assertTrue(use.version().isPresent()); - assertEquals(1, use.version().get()); - assertTrue(use.id().isPresent()); - assertEquals((int)0, (int)use.id().get()); - assertEquals("UEntity{name='body.access', version=1, id=0, markedResolved=true}", use.toString()); + @DisplayName("Test creating a software entity for use in micro format UUri with null id") + public void test_create_use_for_use_with_micro_format_uuri_with_null_id() { + UEntity use = UEntity.microFormat(null); + assertTrue(use.name().isBlank()); + assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertTrue(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertFalse(use.isMicroForm()); } @Test - @DisplayName("Test creating UEntity with invalid id") - public void test_create_use_with_invalid_id() { - UEntity use = UEntity.resolvedFormat("body.access", 1, null); - assertEquals("body.access", use.name()); - assertTrue(use.version().isPresent()); - assertEquals(1, use.version().get()); - assertFalse(use.id().isPresent()); - assertEquals("UEntity{name='body.access', version=1, id=null, markedResolved=false}", use.toString()); + @DisplayName("Test creating a software entity for use in micro format UUri with id and version") + public void test_create_use_for_use_with_micro_format_uuri_with_id_and_version() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.microFormat(id, 1); + assertTrue(use.name().isBlank()); + assertEquals(1, use.version().orElse(-1)); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertTrue(use.isMicroForm()); } @Test - @DisplayName("Test isResolved and isLongForm() with valid resolved information") - public void test_isResolved_with_valid_resolved_data() { - UEntity use = UEntity.resolvedFormat("body.access", 1, (short)0); - assertTrue(use.isResolved()); - assertTrue(use.isLongForm()); - UEntity use3 = UEntity.resolvedFormat("2", null, (short)1); - assertTrue(use3.isResolved()); - assertTrue(use3.isLongForm()); + @DisplayName("Test creating a software entity for use in micro format UUri with id and null version") + public void test_create_use_for_use_with_micro_format_uuri_with_id_and_null_version() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.microFormat(id, null); + assertTrue(use.name().isBlank()); + assertTrue(use.version().isEmpty()); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertTrue(use.isMicroForm()); } @Test - @DisplayName("Test isResolved and isLongForm() with invalid resolved data") - public void test_isResolved_with_invalid_resolved_data() { - UEntity use = UEntity.resolvedFormat("body.access", 1, null); + @DisplayName("Test creating a software entity for use in micro format UUri with null id and version") + public void test_create_use_for_use_with_micro_format_uuri_with_null_id_and_version() { + UEntity use = UEntity.microFormat(null, 1); + assertTrue(use.name().isBlank()); + assertEquals(1, use.version().orElse(-1)); + assertTrue(use.id().isEmpty()); + assertFalse(use.isEmpty()); assertFalse(use.isResolved()); - assertTrue(use.isLongForm()); + assertFalse(use.isLongForm()); assertFalse(use.isMicroForm()); + } - UEntity use2 = UEntity.microFormat((short)1, null); - assertFalse(use2.isResolved()); - assertFalse(use2.isLongForm()); - assertTrue(use2.isMicroForm()); - - UEntity use3 = UEntity.empty(); - assertFalse(use3.isResolved()); - assertFalse(use3.isLongForm()); - assertFalse(use3.isMicroForm()); - - UEntity use4 = UEntity.resolvedFormat("body.access", 1, (short)4); - assertTrue(use4.isResolved()); - assertTrue(use4.isLongForm()); - assertTrue(use4.isMicroForm()); + @Test + @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri") + public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.resolvedFormat("body.access", 1, id); + assertEquals("body.access", use.name()); + assertEquals(1, use.version().orElse(-1)); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); + assertTrue(use.isResolved()); + assertTrue(use.isLongForm()); + assertTrue(use.isMicroForm()); } @Test - @DisplayName("Test create UEntity calling microFormat with valid id") - public void test_create_use_with_valid_id() { - UEntity use = UEntity.microFormat((short)1); - assertEquals("UEntity{name='', version=null, id=1, markedResolved=false}", use.toString()); - assertTrue(use.id().isPresent()); - assertFalse(use.version().isPresent()); - assertFalse(use.isLongForm()); + @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when name is empty") + public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_when_name_is_empty() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.resolvedFormat("", 1, id); + assertEquals("", use.name()); + assertEquals(1, use.version().orElse(-1)); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); assertTrue(use.isMicroForm()); } - @Test - @DisplayName("Test create resolvedFormat with various scenarios passed to the api") - public void test_create_use_with_valid_id_and_version() { - UEntity use = UEntity.resolvedFormat("body.access", 1, (short)1); - assertEquals("UEntity{name='body.access', version=1, id=1, markedResolved=true}", use.toString()); - assertTrue(use.id().isPresent()); - assertEquals(use.version().get(), (short)1); - assertTrue(use.isLongForm()); + @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri with missing version") + public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_version_is_missing() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.resolvedFormat("body.access", null, id); + assertEquals("body.access", use.name()); + assertTrue(use.version().isEmpty()); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); assertTrue(use.isResolved()); + assertTrue(use.isLongForm()); assertTrue(use.isMicroForm()); + } - UEntity use2 = UEntity.resolvedFormat("body.access", null, (short)1); - assertEquals("UEntity{name='body.access', version=null, id=1, markedResolved=true}", use2.toString()); - assertTrue(use2.id().isPresent()); - assertFalse(use2.version().isPresent()); - assertTrue(use2.isLongForm()); - assertTrue(use2.isResolved()); - assertTrue(use2.isMicroForm()); - - UEntity use3 = UEntity.resolvedFormat("body.access", 1, null); - assertEquals("UEntity{name='body.access', version=1, id=null, markedResolved=false}", use3.toString()); - assertFalse(use3.id().isPresent()); - assertEquals(use3.version().get(), (short)1); - assertTrue(use3.isLongForm()); - assertFalse(use3.isResolved()); - assertFalse(use3.isMicroForm()); - - UEntity use4 = UEntity.resolvedFormat("body.access", null, null); - assertEquals("UEntity{name='body.access', version=null, id=null, markedResolved=false}", use4.toString()); - assertFalse(use4.id().isPresent()); - assertFalse(use4.version().isPresent()); - assertTrue(use4.isLongForm()); - assertFalse(use4.isResolved()); - assertFalse(use4.isMicroForm()); - - UEntity use5 = UEntity.resolvedFormat("", null, null); - assertEquals("UEntity{name='', version=null, id=null, markedResolved=false}", use5.toString()); - assertTrue(use5.name().isEmpty()); - assertFalse(use5.id().isPresent()); - assertFalse(use5.version().isPresent()); - assertFalse(use5.isLongForm()); - assertFalse(use5.isResolved()); - assertFalse(use5.isMicroForm()); - - try { - UEntity use6 = UEntity.resolvedFormat(null, null, null); - } catch (NullPointerException e) { - assertTrue(e.getMessage().contains(" Software Entity must have a name")); - } - + @Test + @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when all elements are empty") + public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_all_empty_elements() { + UEntity use = UEntity.resolvedFormat("", null, null); + assertEquals("", use.name()); + assertTrue(use.version().isEmpty()); + assertTrue(use.id().isEmpty()); + assertTrue(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertFalse(use.isMicroForm()); } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 3f2a31dc..ef97ca14 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -45,336 +45,413 @@ public void testToString() { } @Test - @DisplayName("Test creating a complete Resource") - public void test_create_Resource() { + @DisplayName("Test creating a empty Resource") + public void test_create_empty_Resource() { + UResource uResource = UResource.empty(); + assertTrue(uResource.name().isEmpty()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } + + @Test + @DisplayName("Test creating a Resource to be used in long formatted UUri") + public void test_create_Resource_long_format_uuri() { UResource uResource = UResource.longFormat("door", "front_left", "Door"); assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("front_left", uResource.instance().get()); - assertTrue(uResource.message().isPresent()); - assertEquals("Door", uResource.message().get()); + assertEquals("front_left", uResource.instance().orElse("")); + assertEquals("Door", uResource.message().orElse("")); + assertTrue(uResource.id().isEmpty()); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a Resource with no instance and no message") - public void test_create_Resource_with_no_instance_and_no_message() { - UResource uResource = UResource.longFormat("door", " ", " "); + @DisplayName("Test creating a Resource to be used in long formatted UUri null instance") + public void test_create_Resource_long_format_uuri_null_instance() { + UResource uResource = UResource.longFormat("door", null, "Door"); assertEquals("door", uResource.name()); assertTrue(uResource.instance().isEmpty()); + assertEquals("Door", uResource.message().orElse("")); + assertTrue(uResource.id().isEmpty()); + assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } + + @Test + @DisplayName("Test creating a Resource to be used in long formatted UUri null message") + public void test_create_Resource_long_format_uuri_null_message() { + UResource uResource = UResource.longFormat("door", "front_left", null); + assertEquals("door", uResource.name()); + assertEquals("front_left", uResource.instance().orElse("")); assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } - UResource uResource2 = UResource.longFormat("door", null, null); - assertEquals("door", uResource2.name()); + @Test + @DisplayName("Test creating a Resource to be used in long formatted UUri all values empty") + public void test_create_Resource_long_format_uuri_all_empty_values() { + UResource uResource = UResource.longFormat(null, " ", " "); + assertTrue(uResource.name().isBlank()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); - assertFalse(uResource.isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a Resource using the fromName static method") - public void test_create_Resource_with_no_instance_and_no_message_using_fromName() { - UResource uResource = UResource.longFormat("door"); - assertEquals("door", uResource.name()); + @DisplayName("Test creating a Resource to be used in long formatted UUri blank instance and blank message") + public void test_create_Resource_long_format_uuri_all_empty_values_blank_instance_and_message() { + UResource uResource = UResource.longFormat(" ", " ", " "); + assertTrue(uResource.name().isBlank()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); - assertFalse(uResource.isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a Resource using the fromNameWithInstance static method") - public void test_create_Resource_with_no_message_using_fromName() { - UResource uResource = UResource.longFormat("door", "front_left", null); + @DisplayName("Test creating a Resource to be used in long formatted UUri only name") + public void test_create_Resource_long_format_uuri_only_name() { + UResource uResource = UResource.longFormat("door"); assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("front_left", uResource.instance().get()); + assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a Resource for an RPC command on the resource") - public void test_create_Resource_for_rpc_commands() { - UResource uResource = UResource.forRpcRequest("UpdateDoor"); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("UpdateDoor", uResource.instance().get()); - assertTrue(uResource.isRPCMethod()); - assertFalse(uResource.isEmpty()); + @DisplayName("Test creating a Resource to be used in long formatted UUri only name but null") + public void test_create_Resource_long_format_uuri_only_name_when_null() { + UResource uResource = UResource.longFormat(null); + assertTrue(uResource.name().isBlank()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test if the resource represents an RPC method call") - public void test_Resource_represents_an_rpc_method_call() { - UResource uResource = UResource.forRpcRequest("UpdateDoor"); - assertTrue(uResource.isRPCMethod()); + @DisplayName("Test creating a Resource to be used in long formatted UUri only name but blank") + public void test_create_Resource_long_format_uuri_only_name_when_blank() { + UResource uResource = UResource.longFormat(" "); + assertTrue(uResource.name().isBlank()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test if the resource represents a resource and not an RPC method call") - public void test_Resource_represents_a_resource_and_not_an_rpc_method_call() { - UResource uResource = UResource.longFormat("door"); - assertFalse(uResource.isRPCMethod()); + @DisplayName("Test creating a Resource to be used in micro formatted UUri") + public void test_create_Resource_micro_format_uuri() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.microFormat(id); + assertTrue(uResource.name().isEmpty()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertEquals(id, uResource.id().orElse(notused)); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } - - @Test - @DisplayName("Test creating an empty Resource using the empty static method") - public void test_create_empty_using_empty() { - UResource uResource = UResource.empty(); + @DisplayName("Test creating a Resource to be used in micro formatted UUri id is null") + public void test_create_Resource_micro_format_uuri_id_is_null() { + UResource uResource = UResource.microFormat(null); assertTrue(uResource.name().isEmpty()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test the isEmpty static method") - public void test_is_empty() { - UResource uResource = UResource.empty(); - assertTrue(uResource.isEmpty()); - - UResource uResource2 = UResource.longFormat("", null, null); - assertTrue(uResource2.isEmpty()); - - UResource uResource3 = UResource.longFormat("", "front_left", null); - assertFalse(uResource3.isEmpty()); - - UResource uResource4 = UResource.longFormat("", null, "Door"); - assertFalse(uResource4.isEmpty()); + @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri") + public void test_create_resolved_Resource_long_and_micro_format_uuri() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", id); + assertEquals("door", uResource.name()); + assertEquals("front_left", uResource.instance().orElse("")); + assertEquals("Door", uResource.message().orElse("")); + assertEquals(id, uResource.id().orElse(notused)); + assertFalse(uResource.isEmpty()); + assertTrue(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating an RPC response Resource using the response static method") - public void test_create_rpc_response_using_response_method() { - UResource uResource = UResource.forRpcResponse(); - assertFalse(uResource.name().isEmpty()); - assertEquals("rpc", uResource.name()); - assertEquals("response", uResource.instance().orElse("")); - assertTrue(uResource.message().isEmpty()); + @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty name") + public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_name() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.resolvedFormat(" ", "front_left", "Door", id); + assertTrue(uResource.name().isBlank()); + assertEquals("front_left", uResource.instance().orElse("")); + assertEquals("Door", uResource.message().orElse("")); + assertEquals(id, uResource.id().orElse(notused)); + assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating an UResource with valid id") - public void test_create_UResource_with_valid_id() { - UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", (short)5); + @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty instance") + public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_instance() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.resolvedFormat("door", null, "Door", id); assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("front_left", uResource.instance().get()); - assertTrue(uResource.message().isPresent()); - assertEquals("Door", uResource.message().get()); - assertTrue(uResource.id().isPresent()); - assertEquals((int)5, (int)uResource.id().get()); - assertEquals("UResource{name='door', instance='front_left', message='Door', id=5, markedResolved=true}", uResource.toString()); + assertTrue(uResource.instance().isEmpty()); + assertEquals("Door", uResource.message().orElse("")); + assertEquals(id, uResource.id().orElse(notused)); assertFalse(uResource.isEmpty()); + assertTrue(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating an UResource with invalid id") - public void test_create_UResource_with_invalid_id() { + @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty id") + public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_id() { UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", null); assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("front_left", uResource.instance().get()); - assertTrue(uResource.message().isPresent()); - assertEquals("Door", uResource.message().get()); - assertFalse(uResource.id().isPresent()); - assertEquals("UResource{name='door', instance='front_left', message='Door', id=null, markedResolved=false}", uResource.toString()); + assertEquals("front_left", uResource.instance().orElse("")); + assertEquals("Door", uResource.message().orElse("")); + assertTrue(uResource.id().isEmpty()); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating an UResource by calling fromId static method") - public void test_create_UResource_by_calling_fromId_static_method() { - UResource uResource = UResource.microFormat((short)5); - assertEquals("", uResource.name()); + @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty all") + public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_all() { + UResource uResource = UResource.resolvedFormat(null, " ", " ", null); + assertTrue(uResource.name().isBlank()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isPresent()); - assertEquals((int)5, (int)uResource.id().get()); - assertEquals("UResource{name='', instance='null', message='null', id=5, markedResolved=false}", uResource.toString()); - assertFalse(uResource.isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a response UResource by calling fromId") - public void test_create_response_UResource_by_calling_fromId() { - UResource uResource = UResource.forRpcResponse(); + @DisplayName("Test creating rpc request for long formatted UUri") + public void test_create_rpc_request_long_format() { + UResource uResource = UResource.forRpcRequest("ExecuteDoorCommand"); assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("response", uResource.instance().get()); + assertEquals("ExecuteDoorCommand", uResource.instance().orElse("")); assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isPresent()); - assertEquals((int)0, (int)uResource.id().get()); - assertEquals("UResource{name='rpc', instance='response', message='null', id=0, markedResolved=true}", uResource.toString()); + assertTrue(uResource.id().isEmpty()); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertTrue(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertTrue(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a response UResource passing name, instance, and id") - public void test_create_response_UResource_passing_name_instance_and_id() { - UResource uResource = UResource.resolvedFormat("rpc", "response", null, (short)0); + @DisplayName("Test creating rpc request for long formatted UUri empty command name") + public void test_create_rpc_request_long_format_empty_command_Name() { + UResource uResource = UResource.forRpcRequest(" "); assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("response", uResource.instance().get()); + assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isPresent()); - assertEquals((int)0, (int)uResource.id().get()); - assertEquals("UResource{name='rpc', instance='response', message='null', id=0, markedResolved=true}", uResource.toString()); - assertFalse(uResource.isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); } @Test - @DisplayName("Test creating a request UResource passing name, instance, and id") - public void test_create_request_UResource_passing_name_instance_and_id() { - UResource uResource = UResource.resolvedFormat("rpc", null, null, (short)0); + @DisplayName("Test creating rpc request for long formatted UUri null command name") + public void test_create_rpc_request_long_format_null_command_Name() { + String commandName = null; + UResource uResource = UResource.forRpcRequest(commandName); assertEquals("rpc", uResource.name()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isPresent()); - assertEquals((int)0, (int)uResource.id().get()); - assertEquals("UResource{name='rpc', instance='null', message='null', id=0, markedResolved=false}", uResource.toString()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } + + @Test + @DisplayName("Test creating rpc request for micro formatted UUri") + public void test_create_rpc_request_micro_format() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.forRpcRequest(id); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertEquals(id, uResource.id().orElse(notused)); assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertTrue(uResource.isRPCMethod()); } @Test - @DisplayName("Test isResolved with resolved UResources") - public void test_isResolved_with_resolved_UResources() { - UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", (short)5); + @DisplayName("Test creating rpc request for micro formatted UUri null id") + public void test_create_rpc_request_micro_format_null_id() { + Short id = null; + UResource uResource = UResource.forRpcRequest(id); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } + + @Test + @DisplayName("Test creating resolved rpc request for long and micro formatted UUri") + public void test_create_resolved_rpc_request_long_and_micro_format() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.forRpcRequest("ExecuteDoorCommand", id); + assertEquals("rpc", uResource.name()); + assertEquals("ExecuteDoorCommand", uResource.instance().orElse("")); + assertTrue(uResource.message().isEmpty()); + assertEquals(id, uResource.id().orElse(notused)); + assertFalse(uResource.isEmpty()); assertTrue(uResource.isResolved()); - UResource uResource2 = UResource.forRpcResponse(); - assertTrue(uResource2.isResolved()); - UResource uResource3 = UResource.forRpcRequest("UpdateDoor", (short)5); - assertTrue(uResource3.isResolved()); + assertTrue(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertTrue(uResource.isRPCMethod()); } @Test - @DisplayName("Test isResolved and isLongForm with unresolved UResources") - public void test_isResolved_with_unresolved_UResources() { - UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", null); + @DisplayName("Test creating resolved rpc request for long and micro formatted UUri id is null") + public void test_create_resolved_rpc_request_long_and_micro_format_id_null() { + Short id = null; + UResource uResource = UResource.forRpcRequest("ExecuteDoorCommand", id); + assertEquals("rpc", uResource.name()); + assertEquals("ExecuteDoorCommand", uResource.instance().orElse("")); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertFalse(uResource.isEmpty()); assertFalse(uResource.isResolved()); assertTrue(uResource.isLongForm()); - UResource uResource2 = UResource.longFormat("door"); - assertFalse(uResource2.isResolved()); - assertFalse(uResource2.isLongForm()); - UResource uResource3 = UResource.forRpcRequest("UpdateDoor"); - assertFalse(uResource3.isResolved()); - assertTrue(uResource3.isLongForm()); - UResource uResource4 = UResource.microFormat((short)4); - assertFalse(uResource4.isResolved()); - assertFalse(uResource4.isLongForm()); - - UResource uResource5 = UResource.longFormat("door", "front_left", null); - assertFalse(uResource5.isResolved()); - assertTrue(uResource5.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertTrue(uResource.isRPCMethod()); + } + @Test + @DisplayName("Test creating resolved rpc request for long and micro formatted UUri null method name") + public void test_create_resolved_rpc_request_long_and_micro_format_null_method_name() { + Short id = 42; + Short notused = 0; + UResource uResource = UResource.forRpcRequest(" ", id); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertEquals(id, uResource.id().orElse(notused)); + assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertTrue(uResource.isMicroForm()); + assertTrue(uResource.isRPCMethod()); } @Test - @DisplayName("Test resolved API with all possible combinations of the APIs passed valid and invalid") - public void test_resolved_API_with_all_possible_combinations_of_the_APIs_passed_valid_and_invalid() { - UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", (short)5); - assertTrue(uResource.isResolved()); - UResource uResource2 = UResource.resolvedFormat("door", "front_left", "Door", null); - assertFalse(uResource2.isResolved()); - UResource uResource3 = UResource.resolvedFormat("door", "front_left", null, (short)5); - assertTrue(uResource3.isResolved()); - UResource uResource4 = UResource.resolvedFormat("door", "front_left", null, null); - assertFalse(uResource4.isResolved()); - UResource uResource5 = UResource.resolvedFormat("door", null, "Door", (short)5); - assertFalse(uResource5.isResolved()); - UResource uResource6 = UResource.resolvedFormat("door", null, "Door", null); - assertFalse(uResource6.isResolved()); - UResource uResource7 = UResource.resolvedFormat("door", null, null, (short)5); - assertFalse(uResource7.isResolved()); - UResource uResource8 = UResource.resolvedFormat("door", null, null, null); - assertFalse(uResource8.isResolved()); - UResource uResource9 = UResource.resolvedFormat(null, "front_left", "Door", (short)5); - assertFalse(uResource9.isResolved()); - UResource uResource10 = UResource.resolvedFormat(null, "front_left", "Door", null); - assertFalse(uResource10.isResolved()); - UResource uResource11 = UResource.resolvedFormat(null, "front_left", null, (short)5); - assertFalse(uResource11.isResolved()); - UResource uResource12 = UResource.resolvedFormat(null, "front_left", null, null); - assertFalse(uResource12.isResolved()); - UResource uResource13 = UResource.resolvedFormat(null, null, "Door", (short)5); - assertFalse(uResource13.isResolved()); - UResource uResource14 = UResource.resolvedFormat(null, null, "Door", null); - assertFalse(uResource14.isResolved()); - UResource uResource15 = UResource.resolvedFormat(null, null, null, (short)5); - assertFalse(uResource15.isResolved()); - UResource uResource16 = UResource.resolvedFormat(null, null, null, null); - assertFalse(uResource16.isResolved()); - - - UResource uResource17 = UResource.resolvedFormat("", "front_left", "Door", (short)5); - assertFalse(uResource17.isResolved()); - UResource uResource18 = UResource.resolvedFormat("door", "", "Door", null); - assertFalse(uResource18.isResolved()); - } + @DisplayName("Test creating resolved rpc request for long and micro formatted UUri missing values") + public void test_create_resolved_rpc_request_long_and_micro_format_missing_values() { + UResource uResource = UResource.forRpcRequest(null, null); + assertEquals("rpc", uResource.name()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } @Test - @DisplayName("Test forRpcRequest with null and valid short value") - public void test_forRpcRequest_with_null_and_valid_short_value() { - UResource uResource = UResource.forRpcRequest("UpdateDoor", (short)5); + @DisplayName("Test creating rpc response") + public void test_create_rpc_response() { + Short id = 0; + Short notused = 42; + UResource uResource = UResource.forRpcResponse(); assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isPresent()); - assertEquals("UpdateDoor", uResource.instance().get()); + assertEquals("response", uResource.instance().orElse("")); assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isPresent()); - assertEquals((int)5, (int)uResource.id().get()); + assertEquals(id, uResource.id().orElse(notused)); + assertFalse(uResource.isEmpty()); assertTrue(uResource.isResolved()); assertTrue(uResource.isLongForm()); - assertTrue(uResource.isRPCMethod()); assertTrue(uResource.isMicroForm()); + assertTrue(uResource.isRPCMethod()); + } - UResource uResource2 = UResource.forRpcRequest((Short)null); - assertEquals("rpc", uResource2.name()); - assertFalse(uResource2.instance().isPresent()); - assertTrue(uResource2.message().isEmpty()); - assertFalse(uResource2.id().isPresent()); - assertFalse(uResource2.isResolved()); - assertFalse(uResource2.isLongForm()); - assertTrue(uResource2.isRPCMethod()); - - UResource uResource3 = UResource.forRpcRequest(null, null); - assertEquals("rpc", uResource3.name()); - assertFalse(uResource3.instance().isPresent()); - assertTrue(uResource3.message().isEmpty()); - assertFalse(uResource3.id().isPresent()); - assertFalse(uResource3.isResolved()); - assertFalse(uResource3.isLongForm()); - assertTrue(uResource3.isRPCMethod()); - - UResource uResource4 = UResource.forRpcRequest("", null); - assertEquals("rpc", uResource4.name()); - assertFalse(uResource4.instance().isPresent()); - assertTrue(uResource4.message().isEmpty()); - assertFalse(uResource4.id().isPresent()); - assertFalse(uResource4.isResolved()); - assertFalse(uResource4.isLongForm()); - assertTrue(uResource4.isRPCMethod()); - - UResource uResource6 = UResource.forRpcRequest("hello", null); - assertEquals("rpc", uResource6.name()); - assertTrue(uResource6.instance().isPresent()); - assertTrue(uResource6.message().isEmpty()); - assertFalse(uResource6.id().isPresent()); - assertFalse(uResource6.isResolved()); - assertTrue(uResource6.isLongForm()); - assertTrue(uResource6.isRPCMethod()); - - UResource uResource5 = UResource.forRpcRequest("", (short)2); - assertEquals("rpc", uResource5.name()); - assertFalse(uResource5.instance().isPresent()); - assertTrue(uResource5.message().isEmpty()); - assertTrue(uResource5.id().isPresent()); - assertFalse(uResource5.isResolved()); - assertFalse(uResource5.isLongForm()); - assertTrue(uResource5.isRPCMethod()); - } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java index 64df6824..784f23e5 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java @@ -22,18 +22,15 @@ package org.eclipse.uprotocol.uri.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; - import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertFalse; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.net.InetAddress; import java.net.UnknownHostException; -class UriPartTest { +class UUriTest { @Test @DisplayName("Make sure the equals and hash code works") @@ -51,19 +48,19 @@ public void testToString() { UUri uri = new UUri(uAuthorityLocal, use, uResource); - String expected = "UriPart{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + + String expected = "UriPart{uAuthority=UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}, " + "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + "uResource=UResource{name='door', instance='front_left', message='null', id=null, markedResolved=false}}"; assertEquals(expected, uri.toString()); UUri uriRemote = new UUri(uAuthorityRemote, use, uResource); - String expectedRemote = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + + String expectedRemote = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}, " + "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + "uResource=UResource{name='door', instance='front_left', message='null', id=null, markedResolved=false}}"; assertEquals(expectedRemote, uriRemote.toString()); UUri uri2 = new UUri(uAuthorityRemote, use, UResource.empty()); - String expectedUri2 = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', address='null', markedRemote=true}, " + + String expectedUri2 = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}, " + "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}"; assertEquals(expectedUri2, uri2.toString()); @@ -81,11 +78,15 @@ public void test_create_full_local_uri() { assertEquals(uAuthority, uri.uAuthority()); assertEquals(use, uri.uEntity()); assertEquals(uResource, uri.uResource()); + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @Test - @DisplayName("Test creating full microRemote uri") - public void test_create_full_remote_uri() { + @DisplayName("Test creating full long uri") + public void test_create_full_long_remote_uri() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); UEntity use = UEntity.longFormat("body.access", 1); UResource uResource = UResource.longFormat("door", "front_left", "Door"); @@ -95,6 +96,29 @@ public void test_create_full_remote_uri() { assertEquals(uAuthority, uri.uAuthority()); assertEquals(use, uri.uEntity()); assertEquals(uResource, uri.uResource()); + + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); + } + + @Test + @DisplayName("Test creating rpc response uri") + public void test_create_rpc_response_uri() { + UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); + UEntity use = UEntity.longFormat("body.access", 1); + + UUri uri = UUri.rpcResponse(uAuthority, use); + + assertEquals(uAuthority, uri.uAuthority()); + assertEquals(use, uri.uEntity()); + assertTrue(uri.uResource().isRPCMethod()); + + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @@ -110,6 +134,11 @@ public void test_create_uri_no_message_with_constructor() { assertEquals(uAuthority, uri.uAuthority()); assertEquals(use, uri.uEntity()); assertEquals(uResource, uri.uResource()); + + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @Test @@ -120,6 +149,11 @@ public void test_create_uri_null_authority() { UUri uri = new UUri(null, use, uResource); assertEquals(UAuthority.empty(), uri.uAuthority()); + + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @Test @@ -130,6 +164,11 @@ public void test_create_uri_null_use() { UUri uri = new UUri(uAuthority, null, uResource); assertEquals(UEntity.empty(), uri.uEntity()); + + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @Test @@ -141,6 +180,11 @@ public void test_create_uri_null_uResource() { UUri uri = new UUri(uAuthority, use, uResource); assertEquals(UResource.empty(), uri.uResource()); + + assertFalse(uri.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @Test @@ -151,20 +195,11 @@ public void test_create_empty_using_empty() { assertTrue(uri.uAuthority().isLocal()); assertTrue(uri.uEntity().isEmpty()); assertTrue(uri.uResource().isEmpty()); - } - @Test - @DisplayName("Test the isEmpty static method") - public void test_is_empty() { - UUri uri = UUri.empty(); assertTrue(uri.isEmpty()); - - UAuthority uAuthority = UAuthority.empty(); - UEntity use = UEntity.empty(); - UResource uResource = UResource.empty(); - - UUri uri2 = new UUri(uAuthority, use, uResource); - assertTrue(uri2.isEmpty()); + assertTrue(uri.isLongForm()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); } @Test @@ -173,7 +208,7 @@ public void test_isResolved_and_isLongForm() throws UnknownHostException { UUri uri = UUri.empty(); assertFalse(uri.isResolved()); - assertFalse(uri.isLongForm()); + assertTrue(uri.isLongForm()); assertFalse(uri.isMicroForm()); UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); From 64bedb6557f689d755093bffb6e072d54a130416 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Wed, 20 Sep 2023 20:54:59 +0300 Subject: [PATCH 42/52] fixing the broken build and failing tests --- .../eclipse/uprotocol/uri/datamodel/UUri.java | 5 ++- .../uri/serializer/LongUriSerializerTest.java | 32 ++++++++----------- .../utransport/datamodel/UAttributeTest.java | 11 +++---- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java index d8aa175f..b629b4ad 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java @@ -91,15 +91,14 @@ public static UUri empty() { */ @Override public boolean isEmpty() { - return uAuthority.isLocal() && uEntity().isEmpty() - && uResource.isEmpty(); + return uAuthority.isEmpty() && uEntity().isEmpty() && uResource.isEmpty(); } /** * Returns true if URI contains both names and numeric representations of the names inside its belly. * Meaning that this UUri can be serialized to long or micro formats. * @return Returns true if URI contains both names and numeric representations of the names inside its belly. - * Meaning that this UUri can be serialized to long or micro formats. + * Meaning that this UUri can buree serialized to long or micro formats. */ @Override public boolean isResolved() { diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index 3afc1862..b673edb7 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -22,7 +22,7 @@ public void test_using_the_serializers() { final String strUri = UriSerializer.LONG.serialize(uri); assertEquals("/hartley//rpc.raise", strUri); final UUri uri2 = UriSerializer.LONG.deserialize(strUri); - assertTrue(uri.equals(uri2)); + assertEquals(uri, uri2); } @Test @@ -62,7 +62,7 @@ public void test_parse_protocol_uri_with_schema_and_slash() { public void test_parse_protocol_uri_with_schema_and_double_slash() { String uri = "//"; UUri Uri = UriSerializer.LONG.deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); + assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); } @@ -72,7 +72,7 @@ public void test_parse_protocol_uri_with_schema_and_double_slash() { public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { String uri = "///body.access"; UUri Uri = UriSerializer.LONG.deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); + assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isEmpty()); @@ -84,7 +84,7 @@ public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { String uri = "////body.access"; UUri Uri = UriSerializer.LONG.deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); + assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().name().isBlank()); assertTrue(Uri.uEntity().version().isEmpty()); @@ -96,12 +96,11 @@ public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { String uri = "/////body.access"; UUri Uri = UriSerializer.LONG.deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); + assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().isEmpty()); assertEquals("body", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("access", Uri.uResource().instance().get()); + assertEquals("access", Uri.uResource().instance().orElse("")); assertTrue(Uri.uResource().message().isEmpty()); } @@ -110,7 +109,7 @@ public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { String uri = "//////body.access"; UUri Uri = UriSerializer.LONG.deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); + assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); } @@ -135,8 +134,7 @@ public void test_parse_protocol_uri_with_local_service_with_version() { assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().orElse(10)); assertTrue(Uri.uResource().isEmpty()); } @@ -162,8 +160,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); + assertEquals(1, Uri.uEntity().version().orElse(10)); assertEquals("door", Uri.uResource().name()); assertTrue(Uri.uResource().instance().isEmpty()); assertTrue(Uri.uResource().message().isEmpty()); @@ -885,16 +882,13 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { UUri Uri = UriSerializer.LONG.deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("vin", Uri.uAuthority().domain().get()); + assertEquals("vcu", Uri.uAuthority().device().orElse("")); + assertEquals("vin", Uri.uAuthority().domain().orElse("")); assertEquals("body.access", Uri.uEntity().name()); assertTrue(Uri.uEntity().version().isEmpty()); assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertEquals("front_left", Uri.uResource().instance().orElse("")); + assertEquals("Door", Uri.uResource().message().orElse("")); assertEquals(uri2, UriSerializer.LONG.serialize(Uri)); } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java index 4471f335..9f5672a9 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java @@ -66,12 +66,11 @@ public void testToString() { .withCommStatus(5) .build(); assertEquals(String.format("UAttributes{id=%s, type=RESPONSE, priority=LOW, ttl=1000, token='someToken', " + - "sink=UriPart{uAuthority=UAuthority{device='null', domain='null', address='null', markedRemote=false}, " + - "uEntity=UEntity{name='body.access', version=null, id=null, markedResolved=false}, " + - "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}, " + - "plevel=1, commstatus=5, reqid=%s}", - id,requestId), - uAttributes.toString()); + "sink=UriPart{uAuthority=UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}, " + + "uEntity=UEntity{name='body.access', version=null, id=null, markedResolved=false}, " + + "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}, plevel=1, commstatus=5, " + + "reqid=%s}",id, requestId),uAttributes.toString()); + } @Test From 454c0142692b4eb1c80fc6cc0add7cd7aa8cd402 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Wed, 20 Sep 2023 21:26:10 +0300 Subject: [PATCH 43/52] fixing some dead code and tests --- .../uprotocol/uri/datamodel/UEntity.java | 4 ++-- .../uprotocol/uri/datamodel/UEntityTest.java | 19 +++++++++++++++++-- .../uri/datamodel/UResourceTest.java | 17 ++++++++++++++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java index 94c5198d..40312605 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java @@ -64,8 +64,8 @@ private UEntity(String name, Integer version, Short id, boolean markedResolved) * @return Returns a complete UEntity with all the information so that it can be used in long form UUri serialisation and micro form UUri serialisation. */ public static UEntity resolvedFormat(String name, Integer version, Short id) { - boolean resolved = name != null && !name.isEmpty() && id != null; - return new UEntity(name, version, id, resolved); + boolean resolved = name != null && !name.isBlank() && id != null; + return new UEntity(Objects.requireNonNullElse(name, "").trim(), version, id, resolved); } /** diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java index 90c26747..7231cf63 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java @@ -235,7 +235,22 @@ public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_for public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_when_name_is_empty() { Short id = 42; Short defaultNotUsed = 0; - UEntity use = UEntity.resolvedFormat("", 1, id); + UEntity use = UEntity.resolvedFormat(" ", 1, id); + assertEquals("", use.name()); + assertEquals(1, use.version().orElse(-1)); + assertEquals(id, use.id().orElse(defaultNotUsed)); + assertFalse(use.isEmpty()); + assertFalse(use.isResolved()); + assertFalse(use.isLongForm()); + assertTrue(use.isMicroForm()); + } + + @Test + @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when name is null") + public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_when_name_is_null() { + Short id = 42; + Short defaultNotUsed = 0; + UEntity use = UEntity.resolvedFormat(null, 1, id); assertEquals("", use.name()); assertEquals(1, use.version().orElse(-1)); assertEquals(id, use.id().orElse(defaultNotUsed)); @@ -263,7 +278,7 @@ public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_for @Test @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when all elements are empty") public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_all_empty_elements() { - UEntity use = UEntity.resolvedFormat("", null, null); + UEntity use = UEntity.resolvedFormat(" ", null, null); assertEquals("", use.name()); assertTrue(use.version().isEmpty()); assertTrue(use.id().isEmpty()); diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index ef97ca14..3940e620 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -48,7 +48,22 @@ public void testToString() { @DisplayName("Test creating a empty Resource") public void test_create_empty_Resource() { UResource uResource = UResource.empty(); - assertTrue(uResource.name().isEmpty()); + assertTrue(uResource.name().isBlank()); + assertTrue(uResource.instance().isEmpty()); + assertTrue(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertTrue(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } + + @Test + @DisplayName("Test creating a empty Resource") + public void test_create_empty_Resource2() { + UResource uResource = UResource.longFormat(" ", null, null); + assertTrue(uResource.name().isBlank()); assertTrue(uResource.instance().isEmpty()); assertTrue(uResource.message().isEmpty()); assertTrue(uResource.id().isEmpty()); From bf5dc2466f927eee2854f64c060da078ca617f71 Mon Sep 17 00:00:00 2001 From: tamarafischer Date: Thu, 21 Sep 2023 21:24:39 +0300 Subject: [PATCH 44/52] working on serialization --- .../cloudevent/factory/CloudEventFactory.java | 3 +- .../validate/CloudEventValidator.java | 17 +- .../uri/serializer/LongUriSerializer.java | 26 ++- .../uri/serializer/MicroUriSerializer.java | 80 ++++--- .../uri/serializer/UriSerializer.java | 72 +++--- .../uprotocol/uri/validator/UriValidator.java | 39 +--- .../factory/CloudEventFactoryTest.java | 47 ++-- .../cloudevent/factory/UCloudEventTest.java | 19 +- .../CloudEventToJsonSerializerTest.java | 17 +- .../CloudEventToProtobufSerializerTest.java | 17 +- .../validate/CloudEventValidatorTest.java | 16 +- .../org/eclipse/uprotocol/rpc/RpcTest.java | 5 +- .../uri/serializer/LongUriSerializerTest.java | 221 ++++++++++-------- .../serializer/MicroUriSerializerTest.java | 54 ++--- .../uri/validator/UUriValidatorTest.java | 58 ++--- .../validator/UAttributesValidatorTest.java | 20 +- 16 files changed, 352 insertions(+), 359 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java b/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java index 509787b5..3a931735 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java @@ -159,8 +159,7 @@ static String generateCloudEventId() { * * @param id Event unique identifier. * @param source Identifies who is sending this event in the format of a uProtocol URI that - * can be built from a {@link UUri} object using - * the {@link UriFactory} + * can be built from a {@link UUri} object. * @param protoPayloadBytes The serialized Event data with the content type of "application/x-protobuf". * @param protoPayloadSchema The schema of the proto payload bytes, for example you can use protoPayload.getTypeUrl() on your service/app object. * @param attributes Additional cloud event attributes that can be passed in. All attributes are optional and will be added only if they diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java index 301dbc1e..8001ee24 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java @@ -21,16 +21,15 @@ package org.eclipse.uprotocol.cloudevent.validate; +import com.google.rpc.Code; +import com.google.rpc.Status; +import io.cloudevents.CloudEvent; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; - -import com.google.rpc.Code; -import com.google.rpc.Status; -import io.cloudevents.CloudEvent; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import java.util.Optional; import java.util.stream.Collectors; @@ -152,7 +151,7 @@ public ValidationResult validateSink(CloudEvent cloudEvent) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateUEntityUri(String uri) { - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); return validateUEntityUri(Uri); } @@ -175,7 +174,7 @@ public static ValidationResult validateUEntityUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateTopicUri(String uri) { - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); return validateTopicUri(Uri); } @@ -206,7 +205,7 @@ public static ValidationResult validateTopicUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcTopicUri(String uri) { - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); return validateRpcTopicUri(Uri); } @@ -234,7 +233,7 @@ public static ValidationResult validateRpcTopicUri(UUri Uri) { * @return Returns the ValidationResult containing a success or a failure with the error message. */ public static ValidationResult validateRpcMethod(String uri) { - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); ValidationResult validationResult = validateUEntityUri(Uri); if (validationResult.isFailure()){ return ValidationResult.failure(String.format("Invalid RPC method uri. %s", validationResult.getMessage())); diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index 68553dcf..d0dfa3e8 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -33,21 +33,27 @@ /** * UUri Serializer that serializes a UUri to a string (long format) per - * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + * <<a href="...">...</a> */ public class LongUriSerializer implements UriSerializer { + private static final LongUriSerializer INSTANCE = new LongUriSerializer(); + + private LongUriSerializer(){} + + public static LongUriSerializer instance() { + return INSTANCE; + } + /** - * Serialize the UUri object Into a string in Long Form. - * - * @param Uri The URI data object. - * @return Returns the uProtocol URI string from an URI data object - * that can be used as a sink or a source in a uProtocol publish communication. + * Support for serializing {@link UUri} objects into their String format. + * @param Uri {@link UUri} object to be serialized to the String format. + * @return Returns the String format of the supplied {@link UUri} that can be used as a sink or a source in a uProtocol publish communication. */ @Override public String serialize(UUri Uri) { if (Uri == null || Uri.isEmpty()) { - return new String(); + return ""; } StringBuilder sb = new StringBuilder(); @@ -189,9 +195,7 @@ public UUri deserialize(String uProtocolUri) { if (!useVersion.isBlank()) { useVersionInt = Integer.valueOf(useVersion); } - } catch (NumberFormatException e) { - useVersionInt = null; - } + } catch (NumberFormatException ignored) {} return new UUri(uAuthority, UEntity.longFormat(useName, useVersionInt), uResource); } @@ -200,7 +204,7 @@ public UUri deserialize(String uProtocolUri) { * Static factory method for creating a UResource using a string that contains * name + instance + message. * @param resourceString String that contains the UResource information. - * @return Returns a UResource object + * @return Returns a UResource object. */ private static UResource parseFromString(String resourceString) { Objects.requireNonNull(resourceString, " Resource must have a command name."); diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index 4a93e10b..dac13b6e 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -35,7 +35,7 @@ /** * UUri Serializer that serializes a UUri to a byte[] (micro format) per - * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + * ... */ public class MicroUriSerializer implements UriSerializer { @@ -47,6 +47,14 @@ public class MicroUriSerializer implements UriSerializer { static final byte UP_VERSION = 0x1; // UP version + private static final MicroUriSerializer INSTANCE = new MicroUriSerializer(); + + private MicroUriSerializer(){} + + public static MicroUriSerializer instance() { + return INSTANCE; + } + /** * The type of address used for Micro URI. */ @@ -57,7 +65,7 @@ private enum AddressType { private final int value; - private AddressType(int value) { + AddressType(int value) { this.value = value; } @@ -73,10 +81,10 @@ public static Optional from(int value) { } /** - * Serialize a UUri into a byte[] following the Micro-URI specifications - * - * @param Uri The URI data object. - * @return Returns the serialized URI into a byte[] + * TODO Steven this needs to be fixed + * Serialize a UUri into a byte[] following the Micro-URI specifications. + * @param Uri The {@link UUri} data object. + * @return Returns a byte[] representing the serialized {@link UUri}. */ @Override public byte[] serialize(UUri Uri) { @@ -89,7 +97,7 @@ public byte[] serialize(UUri Uri) { Optional maybeUResourceId = Uri.uResource().id(); // Cannot create a micro URI without UResource ID or uEntity ID - if (!maybeUResourceId.isPresent() || !maybeUeId.isPresent()) { + if (maybeUResourceId.isEmpty() || maybeUeId.isEmpty()) { return new byte[0]; } @@ -109,11 +117,13 @@ public byte[] serialize(UUri Uri) { os.write(maybeUResourceId.get()>>8); os.write(maybeUResourceId.get()); - // UAUTHORITY_ADDRESS - if (maybeAddress.isPresent()) { + // UAUTHORITY_ADDRESS + final Optional maybeUAuthorityAddressBytes = calculateUAuthorityBytes(Uri.uAuthority()); + if (maybeUAuthorityAddressBytes.isPresent()) { try { - os.write(maybeAddress.get().getAddress()); + os.write(maybeUAuthorityAddressBytes.get()); } catch (IOException e) { + //TODO Steven this is not correct - maybe write an empty byte into the stream return new byte[0]; } } @@ -121,23 +131,27 @@ public byte[] serialize(UUri Uri) { // UENTITY_ID os.write(maybeUeId.get()>>8); os.write(maybeUeId.get()); - + // UE_VERSION Optional version = Uri.uEntity().version(); - os.write(!version.isPresent() ? (byte)0 : version.get().byteValue()); + os.write(version.map(Integer::byteValue).orElseGet(() -> (byte) 0)); // UNUSED os.write((byte)0); return os.toByteArray(); - + + } + + private static Optional calculateUAuthorityBytes(UAuthority uAuthority) { + Optional maybeAddress = uAuthority.address(); + return maybeAddress.map(InetAddress::getAddress); } - /** - * Deserialize a byte[] into a UUri object + * Deserialize a byte[] into a {@link UUri} object. * @param microUri A byte[] uProtocol micro URI. - * @return Returns an URI data object. + * @return Returns an {@link UUri} data object from the serialized format of a microUri. */ @Override public UUri deserialize(byte[] microUri) { @@ -151,45 +165,49 @@ public UUri deserialize(byte[] microUri) { } int uResourceId = ((microUri[2] & 0xFF) << 8) | (microUri[3] & 0xFF); - - Optional maybeAddress = Optional.empty(); Optional type = AddressType.from(microUri[1]); // Validate Type is found - if (!type.isPresent()) { + if (type.isEmpty()) { return UUri.empty(); } // Validate that the microUri is the correct length for the type - if (type.get() == AddressType.LOCAL && microUri.length != LOCAL_MICRO_URI_LENGTH) { + final AddressType addressType = type.get(); + if (addressType == AddressType.LOCAL && microUri.length != LOCAL_MICRO_URI_LENGTH) { return UUri.empty(); } - else if (type.get() == AddressType.IPv4 && microUri.length != IPV4_MICRO_URI_LENGTH) { + else if (addressType == AddressType.IPv4 && microUri.length != IPV4_MICRO_URI_LENGTH) { return UUri.empty(); } - else if (type.get() == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LENGTH) { + else if (addressType == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LENGTH) { return UUri.empty(); } + // Calculate uAuthority + UAuthority uAuthority; int index = 4; - if (!(type.get() == AddressType.LOCAL)) { + if (addressType == AddressType.LOCAL) { + uAuthority = UAuthority.local(); + } else { try { - maybeAddress = Optional.of(InetAddress.getByAddress( - Arrays.copyOfRange(microUri, index, (type.get() == AddressType.IPv4) ? 8 : 20))); + final InetAddress inetAddress = InetAddress.getByAddress( + Arrays.copyOfRange(microUri, index, (addressType == AddressType.IPv4) ? 8 : 20)); + uAuthority = UAuthority.microRemote(inetAddress); } catch (Exception e) { - maybeAddress = Optional.empty(); + uAuthority = UAuthority.local(); } - index += type.get() == AddressType.IPv4 ? 4 : 16; + index += addressType == AddressType.IPv4 ? 4 : 16; } - + // UENTITY_ID int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); // UE_VERSION - int uiVersion = microUri[index++]; - - return new UUri((type.get() == AddressType.LOCAL) ? UAuthority.local() : UAuthority.microRemote(maybeAddress.get()), + int uiVersion = microUri[index]; + + return new UUri(uAuthority, UEntity.microFormat((short)ueId, uiVersion == 0 ? null : uiVersion), UResource.microFormat((short)uResourceId)); } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index 0124e6d2..97e5856e 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -26,81 +26,63 @@ import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; +import java.util.Optional; + /** - * UUri serializer that will serialize to either String or byte[] the UUri object. - * - * For more information, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc - * - * @param T The serialization formation + * UUris are used in transport layers and hence need to be serialised. + * Each transport supports different serialisation formats. + * For more information, please refer to ... + * @param The data structure that the UUri will be serialised into. For example String or byte[]. */ public interface UriSerializer { /** - * Deserialize from the format to a UUri - * @param uri serialized UUri - * @return deserialized UUri object + * Deserialize from the format to a {@link UUri}. + * @param uri serialized UUri. + * @return Returns a {@link UUri} object from the serialized format from the wire. */ UUri deserialize(T uri); /** - * Serialize from a UUri to the format - * @param uri UUri object to be serialized to the format T - * @return serialized UUri + * Serialize from a {@link UUri} to a specific serialization format. + * @param uri UUri object to be serialized to the format T. + * @return Returns the {@link UUri} in the transport serialized format. */ T serialize(UUri uri); /** - * Long form serializer - */ - static LongUriSerializer LONG = new LongUriSerializer(); - - /** - * Micro form serializer - */ - static MicroUriSerializer MICRO = new MicroUriSerializer(); - - - /** - * Deserialize from a both a long and micro into a resolved UUri + * Build a fully resolved {@link UUri} from the serialized long format and the serializes micro format. + * @param longUri {@link UUri} serialized as a Sting. + * @param microUri {@link UUri} serialized as a byte[]. + * @return Returns a {@link UUri} object serialized from one of the forms. */ - default UUri deserialize(String longUri, byte[] microUri) { + default Optional buildResolved(String longUri, byte[] microUri) { - if (longUri == null || longUri.isEmpty() || microUri == null || microUri.length == 0) { - return UUri.empty(); - } - - UUri longUUri = LONG.deserialize(longUri); - UUri microUUri = MICRO.deserialize(microUri); - - - // Check if the UUris built are valid - if (!longUUri.isLongForm() || !microUUri.isMicroForm()) { - return UUri.empty(); - } - - // Both authority types should match (both local or both remote) - if (longUUri.uAuthority().isLocal() != microUUri.uAuthority().isLocal()) { - return UUri.empty(); + if ((longUri == null || longUri.isEmpty()) && (microUri == null || microUri.length == 0)) { + return Optional.of(UUri.empty()); } + UUri longUUri = LongUriSerializer.instance().deserialize(longUri); + UUri microUUri = MicroUriSerializer.instance().deserialize(microUri); UAuthority uAuthority = longUUri.uAuthority().isLocal() ? UAuthority.local() : UAuthority.resolvedRemote( - longUUri.uAuthority().device().get(), + longUUri.uAuthority().device().orElse(null), longUUri.uAuthority().domain().orElse(null), - microUUri.uAuthority().address().get()); + microUUri.uAuthority().address().orElse(null)); UEntity uEntity = UEntity.resolvedFormat( longUUri.uEntity().name(), longUUri.uEntity().version().orElse(null), - microUUri.uEntity().id().get()); + microUUri.uEntity().id().orElse(null)); UResource uResource = UResource.resolvedFormat( longUUri.uResource().name(), longUUri.uResource().instance().orElse(null), longUUri.uResource().message().orElse(null), - microUUri.uResource().id().get()); + microUUri.uResource().id().orElse(null)); - return new UUri(uAuthority, uEntity, uResource); + UUri uUri = new UUri(uAuthority, uEntity, uResource); + return uUri.isResolved() ? Optional.of(uUri) : Optional.empty(); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index 3af39ca2..d2e55bcc 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -2,56 +2,53 @@ import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; - /** * class for validating Uris. */ public interface UriValidator { /** - * Validate a UriPart to ensure that it has at least a name for the uEntity. - * @param uri UriPart to validate. + * Validate a {@link UUri} to ensure that it has at least a name for the uEntity. + * @param uri {@link UUri} to validate. * @return Returns UStatus containing a success or a failure with the error message. */ - public static UStatus validate(UUri uri) { + static UStatus validate(UUri uri) { if (uri.isEmpty()) { - return UStatus.failed("UriPart is empty.", Code.INVALID_ARGUMENT); + return UStatus.failed("Uri is empty.", Code.INVALID_ARGUMENT); } if (uri.uEntity().name().isBlank()) { - return UStatus.failed("UriPart is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); + return UStatus.failed("Uri is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); } return UStatus.ok(); } /** - * Validate a UriPart that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. - * @param uri UriPart to validate. + * Validate a {@link UUri} that is meant to be used as an RPC method URI. Used in Request sink values and Response source values. + * @param uri {@link UUri} to validate. * @return Returns UStatus containing a success or a failure with the error message. */ - public static UStatus validateRpcMethod(UUri uri) { + static UStatus validateRpcMethod(UUri uri) { UStatus status = validate(uri); if (status.isFailed()){ return status; } final UResource uResource = uri.uResource(); if (!uResource.isRPCMethod()) { - return UStatus.failed("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", Code.INVALID_ARGUMENT); + return UStatus.failed("Invalid RPC method uri. Uri should be the method to be called, or method from response.", Code.INVALID_ARGUMENT); } return UStatus.ok(); } /** - * Validate a UriPart that is meant to be used as an RPC response URI. Used in Request source values and Response sink values. - * - * @param uri UriPart to validate. + * Validate a {@link UUri} that is meant to be used as an RPC response URI. Used in Request source values and Response sink values. + * @param uri {@link UUri} to validate. * @return Returns UStatus containing a success or a failure with the error message. */ - public static UStatus validateRpcResponse(UUri uri) { + static UStatus validateRpcResponse(UUri uri) { UStatus status = validate(uri); if (status.isFailed()){ return status; @@ -64,16 +61,4 @@ public static UStatus validateRpcResponse(UUri uri) { return UStatus.ok(); } - - - /** - * Wrapper to validate explicitly a long form URI - * @param uri Long form URI - * @return Returns UStatus containing a success or a failure with the error message. - */ - public static UStatus validateLongUUri(String uri) { - final UUri uUri = UriSerializer.LONG.deserialize(uri); - return validate(uUri); - } - } diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index a696581a..a128e89a 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -21,18 +21,17 @@ package org.eclipse.uprotocol.cloudevent.factory; +import com.google.protobuf.Any; +import com.google.rpc.Code; +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; - -import com.google.protobuf.Any; -import com.google.rpc.Code; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -53,7 +52,7 @@ public void test_create_base_cloud_event() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -95,7 +94,7 @@ public void test_create_base_cloud_event_with_datacontenttype_and_schema() { UEntity use = UEntity.longFormat("body.access"); UUri ultifiUri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(ultifiUri); + String source = LongUriSerializer.instance().serialize(ultifiUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -143,7 +142,7 @@ public void test_create_base_cloud_event_without_attributes() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -180,7 +179,7 @@ public void test_create_publish_cloud_event() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -214,12 +213,12 @@ public void test_create_notification_cloud_event() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // sink UEntity sinkUse = UEntity.longFormat("petapp"); UUri sinkUri = new UUri(UAuthority.longRemote("com.gm.bo", "bo"), sinkUse, "OK"); - String sink = UriSerializer.LONG.serialize(sinkUri); + String sink = LongUriSerializer.instance().serialize(sinkUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -256,13 +255,13 @@ public void test_create_request_cloud_event_from_local_use() { // UriPart for the application requesting the RPC UEntity sourceUse = UEntity.longFormat("petapp"); - String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method UriPart UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); + String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -302,14 +301,14 @@ public void test_create_request_cloud_event_from_remote_use() { // UriPart for the application requesting the RPC UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); UEntity sourceUse = UEntity.longFormat("petapp", 1); - String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method UriPart UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); + String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -348,13 +347,13 @@ public void test_create_response_cloud_event_originating_from_local_use() { // UriPart for the application requesting the RPC UEntity sourceUse = UEntity.longFormat("petapp", 1); - String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method UriPart UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); + String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -395,14 +394,14 @@ public void test_create_response_cloud_event_originating_from_remote_use() { UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); UEntity sourceUse = UEntity.longFormat("petapp"); - String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method UriPart UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); + String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -442,13 +441,13 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use // UriPart for the application requesting the RPC UEntity sourceUse = UEntity.longFormat("petapp", 1); - String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); // service Method UriPart UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); + String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); // additional attributes final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() @@ -487,14 +486,14 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); UEntity sourceUse = UEntity.longFormat("petapp"); - String applicationUriForRPC = UriSerializer.LONG.serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); // service Method UriPart UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), methodSoftwareEntityService, UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = UriSerializer.LONG.serialize(methodUri); + String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); // additional attributes diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java index c6084d76..89686c46 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java @@ -21,20 +21,20 @@ package org.eclipse.uprotocol.cloudevent.factory; +import com.google.protobuf.Any; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.rpc.Code; +import io.cloudevents.CloudEvent; +import io.cloudevents.CloudEventData; +import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.rpc.Code; -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.cloudevents.core.builder.CloudEventBuilder; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -43,7 +43,8 @@ import java.time.Instant; import java.time.OffsetDateTime; import java.time.temporal.ChronoUnit; -import java.util.*; +import java.util.Optional; +import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -683,7 +684,7 @@ private CloudEventBuilder buildBaseCloudEventBuilderForTest() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java index 05ba34b7..625daf34 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java @@ -21,21 +21,20 @@ package org.eclipse.uprotocol.cloudevent.serialize; +import com.google.protobuf.Any; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory; import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; - -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -168,7 +167,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java index caa81dcd..be345fa0 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java @@ -21,6 +21,11 @@ package org.eclipse.uprotocol.cloudevent.serialize; +import com.google.protobuf.Any; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory; @@ -29,13 +34,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; - -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -58,7 +57,7 @@ public void test_serialize_and_desirialize_cloud_event_to_protobuf() { // build the source UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("Door", "front_left", null)); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -148,7 +147,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index 45b14c45..606e0c38 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -21,6 +21,11 @@ package org.eclipse.uprotocol.cloudevent.validate; +import com.google.protobuf.Any; +import com.google.rpc.Code; +import com.google.rpc.Status; +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory; @@ -28,20 +33,15 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; -import com.google.protobuf.Any; -import com.google.rpc.Code; -import com.google.rpc.Status; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.net.URI; import java.util.UUID; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; class CloudEventValidatorTest { @@ -1022,7 +1022,7 @@ private CloudEventBuilder buildBaseCloudEventBuilderForTest() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String source = UriSerializer.LONG.serialize(Uri); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload final Any protoPayload = buildProtoPayloadForTest(); diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 5fc6ca76..03152327 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -26,10 +26,9 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.rpc.Code; import com.google.rpc.Status; - import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UPayload; import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; @@ -542,7 +541,7 @@ private static UPayload buildUPayload() { } private static UUri buildTopic() { - return UriSerializer.LONG.deserialize("//vcu.vin/hartley/1/rpc.Raise"); + return LongUriSerializer.instance().deserialize("//vcu.vin/hartley/1/rpc.Raise"); } private static UAttributes buildUAttributes() { diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index b673edb7..7b95bec4 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -8,6 +8,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Optional; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; @@ -19,28 +20,29 @@ public class LongUriSerializerTest { @DisplayName("Test using the serializers") public void test_using_the_serializers() { final UUri uri = new UUri(UAuthority.local(), UEntity.longFormat("hartley"), UResource.forRpcRequest("raise")); - final String strUri = UriSerializer.LONG.serialize(uri); + final String strUri = LongUriSerializer.instance().serialize(uri); assertEquals("/hartley//rpc.raise", strUri); - final UUri uri2 = UriSerializer.LONG.deserialize(strUri); + final UUri uri2 = LongUriSerializer.instance().deserialize(strUri); assertEquals(uri, uri2); } @Test @DisplayName("Test parse uProtocol uri that is null") public void test_parse_protocol_uri_when_is_null() { - UUri Uri = UriSerializer.LONG.deserialize(null); - assertTrue(Uri.isEmpty()); + UUri uri = LongUriSerializer.instance().deserialize(null); + assertTrue(uri.isEmpty()); + assertFalse(uri.isResolved()); + assertTrue(uri.isLongForm()); } - @Test @DisplayName("Test parse uProtocol uri that is empty string") public void test_parse_protocol_uri_when_is_empty_string() { String uri = ""; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.isEmpty()); - String uri2 = UriSerializer.LONG.serialize(null); + String uri2 = LongUriSerializer.instance().serialize(null); assertTrue(uri2.isEmpty()); } @@ -48,12 +50,12 @@ public void test_parse_protocol_uri_when_is_empty_string() { @DisplayName("Test parse uProtocol uri with schema and slash") public void test_parse_protocol_uri_with_schema_and_slash() { String uri = "/"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); - String uri2 = UriSerializer.LONG.serialize(UUri.empty()); + String uri2 = LongUriSerializer.instance().serialize(UUri.empty()); assertTrue(uri2.isEmpty()); } @@ -61,7 +63,7 @@ public void test_parse_protocol_uri_with_schema_and_slash() { @DisplayName("Test parse uProtocol uri with schema and double slash") public void test_parse_protocol_uri_with_schema_and_double_slash() { String uri = "//"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -71,7 +73,7 @@ public void test_parse_protocol_uri_with_schema_and_double_slash() { @DisplayName("Test parse uProtocol uri with schema and 3 slash and something") public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { String uri = "///body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -83,7 +85,7 @@ public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 4 slash and something") public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { String uri = "////body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().name().isBlank()); @@ -95,7 +97,7 @@ public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 5 slash and something") public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { String uri = "/////body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.uEntity().isEmpty()); @@ -108,7 +110,7 @@ public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { @DisplayName("Test parse uProtocol uri with schema and 6 slash and something") public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { String uri = "//////body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertTrue(Uri.isEmpty()); @@ -118,7 +120,7 @@ public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { @DisplayName("Test parse uProtocol uri with local service no version") public void test_parse_protocol_uri_with_local_service_no_version() { String uri = "/body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -130,7 +132,7 @@ public void test_parse_protocol_uri_with_local_service_no_version() { @DisplayName("Test parse uProtocol uri with local service with version") public void test_parse_protocol_uri_with_local_service_with_version() { String uri = "/body.access/1"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -142,7 +144,7 @@ public void test_parse_protocol_uri_with_local_service_with_version() { @DisplayName("Test parse uProtocol uri with local service no version with resource name only") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_name_only() { String uri = "/body.access//door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -156,7 +158,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource name only") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_name_only() { String uri = "/body.access/1/door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -170,7 +172,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol uri with local service no version with resource and instance only") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance() { String uri = "/body.access//door.front_left"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -185,7 +187,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource and instance only") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_message() { String uri = "/body.access/1/door.front_left"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -201,7 +203,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol uri with local service no version with resource with instance and message") public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance_and_message() { String uri = "/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -217,7 +219,7 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ @DisplayName("Test parse uProtocol uri with local service with version with resource with instance and message") public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_instance_and_message() { String uri = "/body.access/1/door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -234,7 +236,7 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc @DisplayName("Test parse uProtocol RPC uri with local service no version") public void test_parse_protocol_rpc_uri_with_local_service_no_version() { String uri = "/petapp//rpc.response"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); @@ -249,7 +251,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_no_version() { @DisplayName("Test parse uProtocol RPC uri with local service with version") public void test_parse_protocol_rpc_uri_with_local_service_with_version() { String uri = "/petapp/1/rpc.response"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("petapp", Uri.uEntity().name()); @@ -265,7 +267,7 @@ public void test_parse_protocol_rpc_uri_with_local_service_with_version() { @DisplayName("Test parse uProtocol uri with microRemote service only device no domain") public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() { String uri = "//VCU"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -278,7 +280,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() @DisplayName("Test parse uProtocol uri with microRemote service only device and domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() { String uri = "//VCU.MY_CAR_VIN"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -292,7 +294,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() @DisplayName("Test parse uProtocol uri with microRemote service only device and cloud domain") public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_domain() { String uri = "//cloud.uprotocol.example.com"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -306,7 +308,7 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_do @DisplayName("Test parse uProtocol uri with microRemote service no version") public void test_parse_protocol_uri_with_remote_service_no_version() { String uri = "//VCU.MY_CAR_VIN/body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -321,7 +323,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version() { @DisplayName("Test parse uProtocol uri with microRemote cloud service no version") public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { String uri = "//cloud.uprotocol.example.com/body.access"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -336,7 +338,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { @DisplayName("Test parse uProtocol uri with microRemote service with version") public void test_parse_protocol_uri_with_remote_service_with_version() { String uri = "//VCU.MY_CAR_VIN/body.access/1"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -352,7 +354,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version() { @DisplayName("Test parse uProtocol uri with microRemote cloud service with version") public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { String uri = "//cloud.uprotocol.example.com/body.access/1"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -368,7 +370,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { @DisplayName("Test parse uProtocol uri with microRemote service no version with resource name only") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access//door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -385,7 +387,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource name only") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access//door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -402,7 +404,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re @DisplayName("Test parse uProtocol uri with microRemote service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -420,7 +422,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource name only") public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access/1/door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -438,7 +440,7 @@ public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_ @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -456,7 +458,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance no message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -475,7 +477,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -494,7 +496,7 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -513,7 +515,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_message() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -533,7 +535,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource and instance and message") public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_message() { String uri = "//cloud.uprotocol.example.com/body.access/1/door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("cloud", Uri.uAuthority().device().get()); @@ -553,7 +555,7 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_ @DisplayName("Test parse uProtocol uri with microRemote service with version with resource with message when there is only device, no domain") public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_with_message_device_no_domain() { String uri = "//VCU/body.access/1/door.front_left"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("vcu", Uri.uAuthority().device().get()); @@ -571,7 +573,7 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour @DisplayName("Test parse uProtocol RPC uri with microRemote service no version") public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { String uri = "//bo.cloud/petapp//rpc.response"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("bo", Uri.uAuthority().device().get()); @@ -589,7 +591,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { @DisplayName("Test parse uProtocol RPC uri with microRemote service with version") public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { String uri = "//bo.cloud/petapp/1/rpc.response"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isRemote()); assertTrue(Uri.uAuthority().device().isPresent()); assertEquals("bo", Uri.uAuthority().device().get()); @@ -607,7 +609,7 @@ public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { @Test @DisplayName("Test Create a uProtocol URI from null") public void test_build_protocol_uri_from__uri_when__uri_isnull() { - String uProtocolUri = UriSerializer.LONG.serialize(null); + String uProtocolUri = LongUriSerializer.instance().serialize(null); assertEquals("", uProtocolUri); } @@ -615,7 +617,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isnull() { @DisplayName("Test Create a uProtocol URI from an empty URI Object") public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { UUri Uri = UUri.empty(); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("", uProtocolUri); } @@ -624,7 +626,7 @@ public void test_build_protocol_uri_from__uri_when__uri_isEmpty() { public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { UEntity use = UEntity.empty(); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/", uProtocolUri); } @@ -633,7 +635,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_empty_use() { public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access", uProtocolUri); } @@ -642,7 +644,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.empty()); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access/1", uProtocolUri); } @@ -651,7 +653,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access//door", uProtocolUri); } @@ -660,7 +662,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access/1/door", uProtocolUri); } @@ -669,7 +671,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", null)); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access//door.front_left", uProtocolUri); } @@ -678,7 +680,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", null)); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access/1/door.front_left", uProtocolUri); } @@ -687,7 +689,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_message() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access//door.front_left#Door", uProtocolUri); } @@ -696,7 +698,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_message() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("/body.access/1/door.front_left#Door", uProtocolUri); } @@ -705,7 +707,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access", uProtocolUri); } @@ -714,7 +716,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_device_with_domain_with_service_no_version() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//my_car_vin/body.access", uProtocolUri); } @@ -723,7 +725,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_no_ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.empty()); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri); } @@ -732,7 +734,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.empty()); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri); } @@ -741,7 +743,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -750,7 +752,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door", uProtocolUri); } @@ -759,7 +761,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", null)); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left", uProtocolUri); } @@ -768,7 +770,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.longFormat("door", "front_left", null)); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//cloud.uprotocol.example.com/body.access/1/door.front_left", uProtocolUri); } @@ -777,7 +779,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_message() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", null)); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left", uProtocolUri); } @@ -786,7 +788,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access/1/door.front_left#Door", uProtocolUri); } @@ -795,7 +797,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_message() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", "Door")); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("//vcu.my_car_vin/body.access//door.front_left#Door", uProtocolUri); } @@ -804,7 +806,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_local() { UAuthority uAuthority = UAuthority.local(); UEntity use = UEntity.longFormat("petapp", 1); - String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); + String uProtocolUri = LongUriSerializer.instance().serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("/petapp/1/rpc.response", uProtocolUri); } @@ -813,7 +815,7 @@ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_ public void test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_remote() { UAuthority uAuthority = UAuthority.longRemote("cloud", "uprotocol.example.com"); UEntity use = UEntity.longFormat("petapp"); - String uProtocolUri = UriSerializer.LONG.serialize(UUri.rpcResponse(uAuthority, use)); + String uProtocolUri = LongUriSerializer.instance().serialize(UUri.rpcResponse(uAuthority, use)); assertEquals("//cloud.uprotocol.example.com/petapp//rpc.response", uProtocolUri); } @@ -824,7 +826,7 @@ public void test_build_protocol_uri_from_parts_when_they_are_null() { UEntity uSoftwareEntity = null; UResource uResource = null; UUri Uri = new UUri(uAuthority, uSoftwareEntity, uResource); - String uProtocolUri = UriSerializer.LONG.serialize(Uri); + String uProtocolUri = LongUriSerializer.instance().serialize(Uri); assertEquals("", uProtocolUri); } @@ -834,7 +836,7 @@ public void test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authori UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_CAR_VIN"); UEntity use = UEntity.longFormat("body.access", 1); UResource uResource = UResource.longFormat("door"); - String uProtocolUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); + String uProtocolUri = LongUriSerializer.instance().serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri); } @@ -844,7 +846,7 @@ public void test_custom_scheme_no_scheme_empty() { UAuthority uAuthority = null; UEntity uSoftwareEntity = null; UResource uResource = null; - String customUri = UriSerializer.LONG.serialize(new UUri(uAuthority, uSoftwareEntity, uResource)); + String customUri = LongUriSerializer.instance().serialize(new UUri(uAuthority, uSoftwareEntity, uResource)); assertTrue(customUri.isEmpty()); } @@ -854,7 +856,7 @@ public void test_custom_scheme_no_scheme() { UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_CAR_VIN"); UEntity use = UEntity.longFormat("body.access", 1); UResource uResource = UResource.longFormat("door"); - String ucustomUri = UriSerializer.LONG.serialize(new UUri(uAuthority, use, uResource)); + String ucustomUri = LongUriSerializer.instance().serialize(new UUri(uAuthority, use, uResource)); assertEquals("//vcu.my_car_vin/body.access/1/door", ucustomUri); } @@ -862,7 +864,7 @@ public void test_custom_scheme_no_scheme() { @DisplayName("Test parse local uProtocol uri with custom scheme") public void test_parse_local_protocol_uri_with_custom_scheme() { String uri = "custom:/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertTrue(Uri.uAuthority().isLocal()); assertFalse(Uri.uAuthority().isMarkedRemote()); assertEquals("body.access", Uri.uEntity().name()); @@ -879,7 +881,7 @@ public void test_parse_local_protocol_uri_with_custom_scheme() { public void test_parse_remote_protocol_uri_with_custom_scheme() { String uri = "custom://vcu.vin/body.access//door.front_left#Door"; String uri2 = "//vcu.vin/body.access//door.front_left#Door"; - UUri Uri = UriSerializer.LONG.deserialize(uri); + UUri Uri = LongUriSerializer.instance().deserialize(uri); assertFalse(Uri.uAuthority().isLocal()); assertTrue(Uri.uAuthority().isMarkedRemote()); assertEquals("vcu", Uri.uAuthority().device().orElse("")); @@ -889,23 +891,39 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { assertEquals("door", Uri.uResource().name()); assertEquals("front_left", Uri.uResource().instance().orElse("")); assertEquals("Door", Uri.uResource().message().orElse("")); - assertEquals(uri2, UriSerializer.LONG.serialize(Uri)); + assertEquals(uri2, LongUriSerializer.instance().serialize(Uri)); } @Test - @DisplayName("Test deserializer a long and micro uri passing garbage") - void test_deserialize_long_and_micro_passing_garbage() { - UUri uri = UriSerializer.LONG.deserialize(null, null); - assertTrue(uri.isEmpty()); + @DisplayName("Test build resolved uri passing null") + void test_deserialize_long_and_micro_passing_null() { + Optional uri = LongUriSerializer.instance().buildResolved(null, null); + assertTrue(uri.isPresent()); + assertTrue(uri.get().isEmpty()); + } - UUri uri1 = UriSerializer.LONG.deserialize(null, new byte[0]); - assertTrue(uri1.isEmpty()); + @Test + @DisplayName("Test build resolved uri passing null long uri empty byte array") + void test_deserialize_long_and_micro_passing_null_long_uri_empty_byte_array() { + Optional uri = LongUriSerializer.instance().buildResolved(null, new byte[0]); + assertTrue(uri.isPresent()); + assertTrue(uri.get().isEmpty()); + } - UUri uri2 = UriSerializer.LONG.deserialize("", null); - assertTrue(uri2.isEmpty()); + @Test + @DisplayName("Test build resolved uri passing empty long uri null byte array") + void test_deserialize_long_and_micro_passing_nullempty_long_uri_null_byte_array() { + Optional uri = LongUriSerializer.instance().buildResolved("", null); + assertTrue(uri.isPresent()); + assertTrue(uri.get().isEmpty()); + } - UUri uri3 = UriSerializer.LONG.deserialize("", new byte[0]); - assertTrue(uri3.isEmpty()); + @Test + @DisplayName("Test build resolved uri passing empty long uri, empty byte[]") + void test_deserialize_long_and_micro_passing_empty_long_uri_empty_byte_array() { + Optional uri = LongUriSerializer.instance().buildResolved("", new byte[0]); + assertTrue(uri.isPresent()); + assertTrue(uri.get().isEmpty()); } @Test @@ -913,12 +931,12 @@ void test_deserialize_long_and_micro_passing_garbage() { void test_deserialize_long_and_micro_passing_UAuthority_that_doesnt_match() { String longUUri = "//vcu.vin/body.access//door.front_left#Door"; byte[] microUUri = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri = UriSerializer.LONG.deserialize(longUUri, microUUri); + Optional uri = LongUriSerializer.instance().buildResolved(longUUri, microUUri); assertTrue(uri.isEmpty()); String longUUri1 = "/body.access//door.front_left#Door"; byte[] microUUri1 = new byte[] {0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri1 = UriSerializer.LONG.deserialize(longUUri1, microUUri1); + Optional uri1 = LongUriSerializer.instance().buildResolved(longUUri1, microUUri1); assertTrue(uri1.isEmpty()); } @@ -929,27 +947,27 @@ void test_deserialize_long_and_micro_passing_invalid_values() { byte[] goodMicroUUri = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; String badLongUUri = "///"; byte[] badMicroUUri = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri = UriSerializer.LONG.deserialize(goodLongUUri, goodMicroUUri); + Optional uri = LongUriSerializer.instance().buildResolved(goodLongUUri, goodMicroUUri); assertFalse(uri.isEmpty()); - UUri uri2 = UriSerializer.LONG.deserialize(goodLongUUri, badMicroUUri); + Optional uri2 = LongUriSerializer.instance().buildResolved(goodLongUUri, badMicroUUri); assertTrue(uri2.isEmpty()); - UUri uri3 = UriSerializer.LONG.deserialize(badLongUUri, goodMicroUUri); + Optional uri3 = LongUriSerializer.instance().buildResolved(badLongUUri, goodMicroUUri); assertTrue(uri3.isEmpty()); - UUri uri4 = UriSerializer.LONG.deserialize(badLongUUri, badMicroUUri); + Optional uri4 = LongUriSerializer.instance().buildResolved(badLongUUri, badMicroUUri); assertTrue(uri4.isEmpty()); - UUri uri5 = UriSerializer.LONG.deserialize("", goodMicroUUri); + Optional uri5 = LongUriSerializer.instance().buildResolved("", goodMicroUUri); assertTrue(uri5.isEmpty()); - UUri uri6 = UriSerializer.LONG.deserialize("", badMicroUUri); + Optional uri6 = LongUriSerializer.instance().buildResolved("", badMicroUUri); assertTrue(uri6.isEmpty()); - UUri uri7 = UriSerializer.LONG.deserialize(null, goodMicroUUri); + Optional uri7 = LongUriSerializer.instance().buildResolved(null, goodMicroUUri); assertTrue(uri7.isEmpty()); - UUri uri8 = UriSerializer.LONG.deserialize(null, badMicroUUri); + Optional uri8 = LongUriSerializer.instance().buildResolved(null, badMicroUUri); assertTrue(uri8.isEmpty()); - UUri uri9 = UriSerializer.LONG.deserialize(goodLongUUri, null); + Optional uri9 = LongUriSerializer.instance().buildResolved(goodLongUUri, null); assertTrue(uri9.isEmpty()); - UUri uri10 = UriSerializer.LONG.deserialize(goodLongUUri, new byte[0]); + Optional uri10 = LongUriSerializer.instance().buildResolved(goodLongUUri, new byte[0]); assertTrue(uri10.isEmpty()); } @@ -960,9 +978,10 @@ void test_deserialize_long_and_micro_passing_valid_values() throws UnknownHostEx UUri uri = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("hartley", 1, (short)5), UResource.resolvedFormat("raise", "salary", "Pay", (short)2)); - String longUUri = UriSerializer.LONG.serialize(uri); - byte[] microUUri = UriSerializer.MICRO.serialize(uri); - UUri uri2 = UriSerializer.LONG.deserialize(longUUri, microUUri); - assertEquals(uri, uri2); + String longUUri = LongUriSerializer.instance().serialize(uri); + byte[] microUUri = MicroUriSerializer.instance().serialize(uri); + UUri notused = UUri.empty(); + Optional uri2 = LongUriSerializer.instance().buildResolved(longUUri, microUUri); + assertEquals(uri, uri2.orElse(UUri.empty())); } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java index 03cb9ef5..92604489 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java @@ -22,22 +22,22 @@ public class MicroUriSerializerTest @DisplayName("Test serialize and deserialize empty content") public void test_empty() { UUri uri = UUri.empty(); - byte[] bytes = UriSerializer.MICRO.serialize(uri); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); assertEquals(bytes.length, 0); - UUri uri2 = UriSerializer.MICRO.deserialize(bytes); + UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); assertTrue(uri2.isEmpty()); } @Test @DisplayName("Test serialize and deserialize null content") public void test_null() { - byte[] bytes = UriSerializer.MICRO.serialize(null); + byte[] bytes = MicroUriSerializer.instance().serialize(null); assertEquals(bytes.length, 0); - UUri uri2 = UriSerializer.MICRO.deserialize(null); + UUri uri2 = MicroUriSerializer.instance().deserialize(null); assertTrue(uri2.isEmpty()); } @@ -50,8 +50,8 @@ public void test_serialize_uri() { UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.MICRO.serialize(uri); - UUri uri2 = UriSerializer.MICRO.deserialize(bytes); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); + UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); assertEquals(uri, uri2); } @@ -66,29 +66,29 @@ public void test_serialize_uri_without_version() { UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.MICRO.serialize(uri); - UUri uri2 = UriSerializer.MICRO.deserialize(bytes); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); + UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); assertEquals(uri, uri2); } @Test @DisplayName("Test serialize invalid UUris") - public void test_serialize_invalid_uuris() throws UnknownHostException { + public void test_serialize_invalid_uuris() { UUri uri = new UUri(UAuthority.local(), UEntity.microFormat((short)1, null), UResource.empty()); - byte[] bytes = UriSerializer.MICRO.serialize(uri); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); assertEquals(bytes.length, 0); UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); - byte[] bytes2 = UriSerializer.MICRO.serialize(uri2); + byte[] bytes2 = MicroUriSerializer.instance().serialize(uri2); assertEquals(bytes2.length, 0); UUri uri3 = new UUri(UAuthority.longRemote("null", "null"), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); - byte[] bytes3 = UriSerializer.MICRO.serialize(uri3); + byte[] bytes3 = MicroUriSerializer.instance().serialize(uri3); assertEquals(bytes3.length, 0); UUri uri4 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); - byte[] bytes4 = UriSerializer.MICRO.serialize(uri4); + byte[] bytes4 = MicroUriSerializer.instance().serialize(uri4); assertEquals(bytes4.length, 0); } @@ -100,8 +100,8 @@ public void test_serialize_ipv4_uri() throws UnknownHostException { UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.MICRO.serialize(uri); - UUri uri2 = UriSerializer.MICRO.deserialize(bytes); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); + UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); assertEquals(uri, uri2); } @@ -113,8 +113,8 @@ public void test_serialize_ipv6_uri() throws UnknownHostException { UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.MICRO.serialize(uri); - UUri uri2 = UriSerializer.MICRO.deserialize(bytes); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); + UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); assertEquals(uri, uri2); } @@ -125,54 +125,54 @@ public void test_deserialize_with_missing_information() throws UnknownHostExcept UEntity use = UEntity.microFormat((short)2, 1); UResource uResource = UResource.microFormat((short)3); UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = UriSerializer.MICRO.serialize(uri); + byte[] bytes = MicroUriSerializer.instance().serialize(uri); // invalid version byte[] byte1 = Arrays.copyOf(bytes, bytes.length); byte1[0] = 0x0; - UUri uri1 = UriSerializer.MICRO.deserialize(byte1); + UUri uri1 = MicroUriSerializer.instance().deserialize(byte1); assertTrue(uri1.isEmpty()); // Invalid type byte[] byte2 = Arrays.copyOf(bytes, bytes.length); byte2[1] = Byte.MAX_VALUE; - UUri uri2 = UriSerializer.MICRO.deserialize(byte2); + UUri uri2 = MicroUriSerializer.instance().deserialize(byte2); assertTrue(uri2.isEmpty()); // Wrong size (local) byte[] byte3 = new byte[] {0x1, 0x0, 0x0, 0x0}; - UUri uri3 = UriSerializer.MICRO.deserialize(byte3); + UUri uri3 = MicroUriSerializer.instance().deserialize(byte3); assertTrue(uri3.isEmpty()); // Wrong size (ipv4) byte[] byte4 = new byte[] {0x1, 0x1, 0x0, 0x0}; - UUri uri4 = UriSerializer.MICRO.deserialize(byte4); + UUri uri4 = MicroUriSerializer.instance().deserialize(byte4); assertTrue(uri4.isEmpty()); // Wrong size (ipv6) byte[] byte5 = new byte[] {0x1, 0x1, 0x0, 0x0}; - UUri uri5 = UriSerializer.MICRO.deserialize(byte5); + UUri uri5 = MicroUriSerializer.instance().deserialize(byte5); assertTrue(uri5.isEmpty()); // Right local size (local) byte[] byte6 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri6 = UriSerializer.MICRO.deserialize(byte6); + UUri uri6 = MicroUriSerializer.instance().deserialize(byte6); assertFalse(uri6.isEmpty()); // IPv4 type local size byte[] byte7 = new byte[] {0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri7 = UriSerializer.MICRO.deserialize(byte7); + UUri uri7 = MicroUriSerializer.instance().deserialize(byte7); assertTrue(uri7.isEmpty()); // IPv6 type local size byte[] byte8 = new byte[] {0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri8 = UriSerializer.MICRO.deserialize(byte8); + UUri uri8 = MicroUriSerializer.instance().deserialize(byte8); assertTrue(uri8.isEmpty()); // Local type but too large byte[] byte9 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri9 = UriSerializer.MICRO.deserialize(byte9); + UUri uri9 = MicroUriSerializer.instance().deserialize(byte9); assertTrue(uri9.isEmpty()); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java index ff78b4a3..e12eae57 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java @@ -22,46 +22,44 @@ package org.eclipse.uprotocol.uri.validator; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; - -import org.eclipse.uprotocol.uri.serializer.UriSerializer; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UStatus; import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; class UUriValidatorTest { @Test @DisplayName("Test validate blank uri") public void test_validate_blank_uri() { - final UUri uri = UriSerializer.LONG.deserialize(null); + final UUri uri = LongUriSerializer.instance().deserialize(null); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @DisplayName("Test validate uri with no device name") public void test_validate_uri_with_no_entity_name() { - final UUri uri = UriSerializer.LONG.deserialize("//"); + final UUri uri = LongUriSerializer.instance().deserialize("//"); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @DisplayName("Test validate uri with uEntity") public void test_validate_uri_with_uEntity() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley"); + final UUri uri = LongUriSerializer.instance().deserialize("/hartley"); final UStatus status = UriValidator.validate(uri); assertEquals(UStatus.ok(), status); } @@ -69,11 +67,11 @@ public void test_validate_uri_with_uEntity() { @Test @DisplayName("Test validate with malformed URI") public void test_validate_with_malformed_uri() { - final UUri uri = UriSerializer.LONG.deserialize("hartley"); + final UUri uri = LongUriSerializer.instance().deserialize("hartley"); final UStatus status = UriValidator.validate(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @@ -84,13 +82,13 @@ public void test_validate_with_blank_uentity_name_uri() { final UStatus status = UriValidator.validate(uri); assertFalse(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.msg()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); } @Test @DisplayName("Test validateRpcMethod with valid URI") public void test_validateRpcMethod_with_valid_uri() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.echo"); + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(UStatus.ok(), status); } @@ -98,26 +96,26 @@ public void test_validateRpcMethod_with_valid_uri() { @Test @DisplayName("Test validateRpcMethod with valid URI") public void test_validateRpcMethod_with_invalid_uri() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley/echo"); + final UUri uri = LongUriSerializer.instance().deserialize("/hartley/echo"); final UStatus status = UriValidator.validateRpcMethod(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.msg()); + assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.msg()); } @Test @DisplayName("Test validateRpcMethod with malformed URI") public void test_validateRpcMethod_with_malformed_uri() { - final UUri uri = UriSerializer.LONG.deserialize("hartley"); + final UUri uri = LongUriSerializer.instance().deserialize("hartley"); final UStatus status = UriValidator.validateRpcMethod(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @DisplayName("Test validateRpcResponse with valid URI") public void test_validateRpcResponse_with_valid_uri() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.response"); + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.response"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(UStatus.ok(), status); } @@ -125,17 +123,17 @@ public void test_validateRpcResponse_with_valid_uri() { @Test @DisplayName("Test validateRpcResponse with malformed URI") public void test_validateRpcResponse_with_malformed_uri() { - final UUri uri = UriSerializer.LONG.deserialize("hartley"); + final UUri uri = LongUriSerializer.instance().deserialize("hartley"); final UStatus status = UriValidator.validateRpcResponse(uri); assertTrue(uri.isEmpty()); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @DisplayName("Test validateRpcResponse with rpc type") public void test_validateRpcResponse_with_rpc_type() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley//dummy.wrong"); + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//dummy.wrong"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); @@ -144,18 +142,10 @@ public void test_validateRpcResponse_with_rpc_type() { @Test @DisplayName("Test validateRpcResponse with invalid rpc response type") public void test_validateRpcResponse_with_invalid_rpc_response_type() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.wrong"); + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.wrong"); final UStatus status = UriValidator.validateRpcResponse(uri); assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); assertEquals("Invalid RPC response type.", status.msg()); } - @Test - @DisplayName("Test validateLongUUri with valid URI") - public void test_validateLongUUri_with_valid_uri() { - final UUri uri = UriSerializer.LONG.deserialize("/hartley//rpc.echo"); - final UStatus status = UriValidator.validateLongUUri(UriSerializer.LONG.serialize(uri)); - assertEquals(UStatus.ok(), status); - } - } diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java index 5190bc1f..c24593ff 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java @@ -25,7 +25,7 @@ import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.UriSerializer; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.utransport.datamodel.UAttributes; import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; import org.eclipse.uprotocol.utransport.datamodel.UMessageType; @@ -167,7 +167,7 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_sink() final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @@ -551,7 +551,7 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_s final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); final UStatus status = validator.validate(attributes); assertTrue(status.isFailed()); - assertEquals("UriPart is missing uSoftware Entity name.", status.msg()); + assertEquals("Uri is missing uSoftware Entity name.", status.msg()); } @Test @@ -763,7 +763,7 @@ public void test_validating_valid_id_attribute() { @Test @DisplayName("test validating invalid sink attribute") public void test_validating_invalid_sink_attribute() { - final UUri uri = UriSerializer.LONG.deserialize("//"); + final UUri uri = LongUriSerializer.instance().deserialize("//"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); @@ -772,13 +772,13 @@ public void test_validating_invalid_sink_attribute() { assertTrue(status.isFailed()); assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("UriPart is empty.", status.msg()); + assertEquals("Uri is empty.", status.msg()); } @Test @DisplayName("test validating valid sink attribute") public void test_validating_valid_sink_attribute() { - final UUri uri = UriSerializer.LONG.deserialize("/haartley/1"); + final UUri uri = LongUriSerializer.instance().deserialize("/haartley/1"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); @@ -894,7 +894,7 @@ public void test_validating_valid_commstatus_attribute() { @Test @DisplayName("test validating request message types") public void test_validating_request_message_types() { - final UUri sink = UriSerializer.LONG.deserialize("/hartley/1/rpc.response"); + final UUri sink = LongUriSerializer.instance().deserialize("/hartley/1/rpc.response"); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) @@ -931,7 +931,7 @@ public void test_validating_request_validator_with_wrong_bad_ttl() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) - .withSink(UriSerializer.LONG.deserialize("/hartley/1/rpc.response")) + .withSink(LongUriSerializer.instance().deserialize("/hartley/1/rpc.response")) .withTtl(-1) .build(); @@ -949,7 +949,7 @@ public void test_validating_response_validator_with_wrong_bad_ttl() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) - .withSink(UriSerializer.LONG.deserialize("/hartley/1/rpc.response")) + .withSink(LongUriSerializer.instance().deserialize("/hartley/1/rpc.response")) .withTtl(-1) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); @@ -969,7 +969,7 @@ public void test_validating_response_validator_with_bad_reqid() { final UUID id = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.NETWORK_CONTROL) - .withSink(UriSerializer.LONG.deserialize("/hartley/1/rpc.response")) + .withSink(LongUriSerializer.instance().deserialize("/hartley/1/rpc.response")) .withTtl(100) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); From 4bf168bf9c15ba941ca9462e07aa2961c7451cce Mon Sep 17 00:00:00 2001 From: czfdcn Date: Fri, 22 Sep 2023 12:29:10 -0400 Subject: [PATCH 45/52] Rename utransport to transport --- .../org/eclipse/uprotocol/rpc/RpcClient.java | 4 +- .../org/eclipse/uprotocol/rpc/RpcMapper.java | 2 +- .../{utransport => transport}/README.adoc | 0 .../uprotocol/transport/UTransport.java | 79 +++++++++++++++++++ .../datamodel/UAttributes.java | 2 +- .../datamodel/UListener.java | 2 +- .../datamodel/UMessageType.java | 2 +- .../datamodel/UPayload.java | 2 +- .../datamodel/UPriority.java | 2 +- .../datamodel/USerializationHint.java | 2 +- .../datamodel/UStatus.java | 2 +- .../validate/UAttributesValidator.java | 12 +-- .../uri/serializer/LongUriSerializer.java | 2 +- .../uprotocol/uri/validator/UriValidator.java | 4 +- .../uprotocol/utransport/UTransport.java | 74 ----------------- .../org/eclipse/uprotocol/rpc/RpcTest.java | 7 +- .../datamodel/UAttributeTest.java | 6 +- .../datamodel/UMessageTypeTest.java | 4 +- .../datamodel/UPayloadTest.java | 5 +- .../datamodel/UPriorityTest.java | 4 +- .../datamodel/USerializationHintTest.java | 4 +- .../datamodel/UStatusTest.java | 4 +- .../validator/UAttributesValidatorTest.java | 18 ++--- .../uri/validator/UUriValidatorTest.java | 4 +- 24 files changed, 134 insertions(+), 113 deletions(-) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/README.adoc (100%) create mode 100644 src/main/java/org/eclipse/uprotocol/transport/UTransport.java rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UAttributes.java (99%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UListener.java (91%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UMessageType.java (97%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UPayload.java (98%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UPriority.java (97%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/USerializationHint.java (98%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UStatus.java (99%) rename src/main/java/org/eclipse/uprotocol/{utransport => transport}/validate/UAttributesValidator.java (97%) delete mode 100644 src/main/java/org/eclipse/uprotocol/utransport/UTransport.java rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UAttributeTest.java (98%) rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UMessageTypeTest.java (93%) rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UPayloadTest.java (94%) rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UPriorityTest.java (96%) rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/USerializationHintTest.java (95%) rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/datamodel/UStatusTest.java (98%) rename src/test/java/org/eclipse/uprotocol/{utransport => transport}/validator/UAttributesValidatorTest.java (99%) diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java index 9eacde54..c9add775 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java @@ -23,9 +23,9 @@ import java.util.concurrent.CompletableFuture; +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UPayload; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes; -import org.eclipse.uprotocol.utransport.datamodel.UPayload; /** * RpcClient is an interface used by code generators for uProtocol services defined in proto files such as diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java index 6e95aa83..94cdf1ac 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcMapper.java @@ -30,7 +30,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; -import org.eclipse.uprotocol.utransport.datamodel.UPayload; +import org.eclipse.uprotocol.transport.datamodel.UPayload; /** * RPC Wrapper is an interface that provides static methods to be able to wrap an RPC request with diff --git a/src/main/java/org/eclipse/uprotocol/utransport/README.adoc b/src/main/java/org/eclipse/uprotocol/transport/README.adoc similarity index 100% rename from src/main/java/org/eclipse/uprotocol/utransport/README.adoc rename to src/main/java/org/eclipse/uprotocol/transport/README.adoc diff --git a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java new file mode 100644 index 00000000..674641e1 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.transport; + +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UListener; +import org.eclipse.uprotocol.transport.datamodel.UPayload; +import org.eclipse.uprotocol.transport.datamodel.UStatus; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UUri; + +/** + * 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. + */ + +public interface UTransport { + + /** + * API used to authenticate with the underlining transport layer that the uEntity passed + * matches the transport specific identity. MUST pass a resolved UUri. + * @param uEntity Resolved UEntity + * @return Returns OKSTATUS if authenticate was successful, FAILSTATUS if the calling uE + * is not authenticated. + */ + UStatus authenticate (UEntity uEntity) ; + + + /** + * 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. + */ + UStatus send(UUri topic, UPayload payload, UAttributes attributes); + + /** + * 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. + */ + 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. + * + */ + UStatus unregisterListener(UUri topic, UListener listener); +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java similarity index 99% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java index c90bcba7..21727517 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java @@ -19,7 +19,7 @@ * under the License. */ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import java.util.Objects; import java.util.Optional; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UListener.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java similarity index 91% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/UListener.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java index 32e392e1..1f1ae760 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UListener.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java @@ -1,4 +1,4 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import org.eclipse.uprotocol.uri.datamodel.UUri; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessageType.java similarity index 97% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessageType.java index 48b708b6..83471cae 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UMessageType.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessageType.java @@ -19,7 +19,7 @@ * under the License. */ - package org.eclipse.uprotocol.utransport.datamodel; + package org.eclipse.uprotocol.transport.datamodel; import java.util.Arrays; import java.util.Optional; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java similarity index 98% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java index fe7d0918..5a72f98b 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java @@ -19,7 +19,7 @@ * under the License. */ - package org.eclipse.uprotocol.utransport.datamodel; + package org.eclipse.uprotocol.transport.datamodel; import java.util.Arrays; import java.util.Objects; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPriority.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPriority.java similarity index 97% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPriority.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/UPriority.java index 747e4708..f636bd8f 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UPriority.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPriority.java @@ -1,4 +1,4 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import java.util.Arrays; import java.util.Optional; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java similarity index 98% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java index c90b7a76..dafce93b 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHint.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java @@ -19,7 +19,7 @@ * under the License. */ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import java.util.Arrays; import java.util.Optional; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UStatus.java similarity index 99% rename from src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java rename to src/main/java/org/eclipse/uprotocol/transport/datamodel/UStatus.java index 3347f826..f3373838 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/datamodel/UStatus.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UStatus.java @@ -1,4 +1,4 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import java.util.Arrays; import java.util.Objects; diff --git a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java similarity index 97% rename from src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java rename to src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java index 31fa43fe..2854b60e 100644 --- a/src/main/java/org/eclipse/uprotocol/utransport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java @@ -18,14 +18,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.eclipse.uprotocol.utransport.validate; +package org.eclipse.uprotocol.transport.validate; +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UMessageType; +import org.eclipse.uprotocol.transport.datamodel.UPriority; +import org.eclipse.uprotocol.transport.datamodel.UStatus; +import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; import org.eclipse.uprotocol.uri.validator.UriValidator; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes; -import org.eclipse.uprotocol.utransport.datamodel.UMessageType; -import org.eclipse.uprotocol.utransport.datamodel.UPriority; -import org.eclipse.uprotocol.utransport.datamodel.UStatus; -import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; import org.eclipse.uprotocol.uuid.factory.UUIDUtils; import java.util.Optional; diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index d0dfa3e8..aa675a32 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -33,7 +33,7 @@ /** * UUri Serializer that serializes a UUri to a string (long format) per - * <<a href="...">...</a> + * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ public class LongUriSerializer implements UriSerializer { diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index d2e55bcc..b8f0a96d 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -1,9 +1,9 @@ package org.eclipse.uprotocol.uri.validator; +import org.eclipse.uprotocol.transport.datamodel.UStatus; +import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.utransport.datamodel.UStatus; -import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; /** * class for validating Uris. diff --git a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java b/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java deleted file mode 100644 index badeeb87..00000000 --- a/src/main/java/org/eclipse/uprotocol/utransport/UTransport.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.utransport; - -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes; -import org.eclipse.uprotocol.utransport.datamodel.UListener; -import org.eclipse.uprotocol.utransport.datamodel.UPayload; -import org.eclipse.uprotocol.utransport.datamodel.UStatus; - -/** - * 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. - * @param The type of the UriFormat that the UTransport implementation will use. - * @param The primitive type for the UriFormat (string for long/short or byte[] for micro). - */ - -public interface UTransport { - - /** - * API to register the calling uE with the underlining transport implementation. - * @param uEntity uProtocol UEntity information - * @param token Deployment specific token used to authenticate the calling uE - * @return Returns Status if the registration is successful or not. - */ - UStatus register (UEntity uEntity, byte[] token) ; - - - /** - * Transmit UPayload to the topic using the attributes defined in UTransportAttributes. - * @param topic topic to send the payload to. - * @param payload Actual payload. - * @param attributes Additional transport attributes. - * @return Returns an Status if managed to send to the underlying communication technology or not. - */ - UStatus send(UUri topic, UPayload payload, UAttributes attributes); - - /** - * Register a method that will be called when a message comes in on the specific topic. - * @param topic Topic the message that arrived via the underlying transport technology. - * @param listener The method to execute to process the date for the topic. - * @return Returns an Ack if the method is registered successfully. - */ - UStatus registerListener(UUri topic, UListener listener); - - /** - * Unregister a method on a topic. Messages arriving on this topic will no longer be processed by this listener. - * @param topic Topic the message that arrived via the underlying transport technology. - * @param listener The method to execute to process the date for the topic. - * @return Returns an Ack if the method is removed successfully. - * - */ - UStatus unregisterListener(UUri topic, UListener listener); -} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 03152327..2efa0971 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -26,12 +26,13 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.rpc.Code; import com.google.rpc.Status; + +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UPayload; +import org.eclipse.uprotocol.transport.datamodel.USerializationHint; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes; -import org.eclipse.uprotocol.utransport.datamodel.UPayload; -import org.eclipse.uprotocol.utransport.datamodel.USerializationHint; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java similarity index 98% rename from src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java rename to src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java index 9f5672a9..1e40625d 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java @@ -19,9 +19,13 @@ * under the License. */ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; + +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UMessageType; +import org.eclipse.uprotocol.transport.datamodel.UPriority; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java similarity index 93% rename from src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java rename to src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java index 78974313..ae576734 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UMessageTypeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java @@ -1,10 +1,12 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; +import org.eclipse.uprotocol.transport.datamodel.UMessageType; + class UMessageTypeTest { @Test diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java similarity index 94% rename from src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java rename to src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java index 856a08e4..9d8f7e9b 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPayloadTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java @@ -1,6 +1,9 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; + +import org.eclipse.uprotocol.transport.datamodel.UPayload; +import org.eclipse.uprotocol.transport.datamodel.USerializationHint; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java similarity index 96% rename from src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java rename to src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java index 5dd95f3a..9fbaf5e4 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UPriorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java @@ -1,4 +1,4 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.eclipse.uprotocol.transport.datamodel.UPriority; + class UPriorityTest { @Test diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java similarity index 95% rename from src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java rename to src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java index 7a08036e..a246b162 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/USerializationHintTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java @@ -1,4 +1,4 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.eclipse.uprotocol.transport.datamodel.USerializationHint; + class USerializationHintTest { @Test diff --git a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java similarity index 98% rename from src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java rename to src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java index eacda56a..fcfc4868 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/datamodel/UStatusTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java @@ -1,7 +1,9 @@ -package org.eclipse.uprotocol.utransport.datamodel; +package org.eclipse.uprotocol.transport.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; + +import org.eclipse.uprotocol.transport.datamodel.UStatus; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java similarity index 99% rename from src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java rename to src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java index c24593ff..70154b1b 100644 --- a/src/test/java/org/eclipse/uprotocol/utransport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java @@ -19,20 +19,20 @@ * under the License. */ -package org.eclipse.uprotocol.utransport.validator; - +package org.eclipse.uprotocol.transport.validator; + +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UMessageType; +import org.eclipse.uprotocol.transport.datamodel.UPriority; +import org.eclipse.uprotocol.transport.datamodel.UStatus; +import org.eclipse.uprotocol.transport.datamodel.UAttributes.UAttributesBuilder; +import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; +import org.eclipse.uprotocol.transport.validate.UAttributesValidator; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes; -import org.eclipse.uprotocol.utransport.datamodel.UAttributes.UAttributesBuilder; -import org.eclipse.uprotocol.utransport.datamodel.UMessageType; -import org.eclipse.uprotocol.utransport.datamodel.UPriority; -import org.eclipse.uprotocol.utransport.datamodel.UStatus; -import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; -import org.eclipse.uprotocol.utransport.validate.UAttributesValidator; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java index e12eae57..782e5469 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java @@ -22,13 +22,13 @@ package org.eclipse.uprotocol.uri.validator; +import org.eclipse.uprotocol.transport.datamodel.UStatus; +import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; -import org.eclipse.uprotocol.utransport.datamodel.UStatus; -import org.eclipse.uprotocol.utransport.datamodel.UStatus.Code; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From cc548997f49ea971ae0fccb302ecbdbeb7f3e67a Mon Sep 17 00:00:00 2001 From: czfdcn Date: Mon, 25 Sep 2023 16:17:06 -0400 Subject: [PATCH 46/52] Adding uMessage --- .../datamodel/CloudEventUMessage.java | 38 +++++++++++++++++++ .../uprotocol/transport/UTransport.java | 16 +++++++- .../transport/datamodel/UListener.java | 15 +++++++- .../transport/datamodel/UMessage.java | 27 +++++++++++++ .../transport/datamodel/UAttributeTest.java | 3 -- 5 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java create mode 100644 src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java b/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java new file mode 100644 index 00000000..2a2009e3 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java @@ -0,0 +1,38 @@ +package org.eclipse.uprotocol.cloudevent.datamodel; + +import java.util.Objects; + +import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UMessage; +import org.eclipse.uprotocol.transport.datamodel.UPayload; +import org.eclipse.uprotocol.transport.datamodel.USerializationHint; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; +import io.cloudevents.CloudEvent; + +public class CloudEventUMessage implements UMessage { + + private final CloudEvent ce; + + public CloudEventUMessage(CloudEvent ce) { + Objects.requireNonNull(ce, "null CloudEvent"); + this.ce = ce; + } + + @Override + public UUri topic() { + return LongUriSerializer.instance().deserialize(UCloudEvent.getSource(ce)); + } + + @Override + public UPayload payload() { + return new UPayload(UCloudEvent.getPayload(ce).toByteArray(), USerializationHint.PROTOBUF); + } + + @Override + public UAttributes attributes() { + return UAttributes.empty(); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java index 674641e1..2c395e1c 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java @@ -21,8 +21,11 @@ package org.eclipse.uprotocol.transport; +import java.util.Objects; + import org.eclipse.uprotocol.transport.datamodel.UAttributes; import org.eclipse.uprotocol.transport.datamodel.UListener; +import org.eclipse.uprotocol.transport.datamodel.UMessage; import org.eclipse.uprotocol.transport.datamodel.UPayload; import org.eclipse.uprotocol.transport.datamodel.UStatus; import org.eclipse.uprotocol.uri.datamodel.UEntity; @@ -44,7 +47,7 @@ public interface UTransport { * @return Returns OKSTATUS if authenticate was successful, FAILSTATUS if the calling uE * is not authenticated. */ - UStatus authenticate (UEntity uEntity) ; + UStatus authenticate(UEntity uEntity) ; /** @@ -56,6 +59,17 @@ public interface UTransport { * returns FAILSTATUS with the appropriate failure. */ UStatus send(UUri topic, UPayload payload, UAttributes attributes); + + /** + * Transmit a UMessage object that contains the topic, payload, and UAttributes. + * @param message UMessage object that contains the topic, payload, and UAttributes. + * @return Returns OKSTATUS if the payload has been successfully sent (ACK'ed), otherwise it + * returns FAILSTATUS with the appropriate failure. + */ + default UStatus send(UMessage message) { + Objects.requireNonNull(message); + return send(message.topic(), message.payload(), message.attributes()); + } /** * Register listener to be called when UPayload is received for the specific topic. diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java index 1f1ae760..6c93f828 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java @@ -1,9 +1,12 @@ package org.eclipse.uprotocol.transport.datamodel; +import java.util.Objects; + import org.eclipse.uprotocol.uri.datamodel.UUri; /** - * For any implementation that defines some kind of callback or function that will be called to handle incoming messages. + * Listener to receive sent events from the uTransport. The Listeners are registered and + * unregistered through the uTransport API. */ public interface UListener { @@ -16,4 +19,14 @@ public interface UListener { */ UStatus onReceive(UUri topic, UPayload payload, UAttributes attributes); + /** + * Method called to handle/process events. + * @param message Message received. + * @return Returns an Ack every time a message is received and processed. + */ + default UStatus OnReceive(UMessage message) { + Objects.requireNonNull(message); + return onReceive(message.topic(), message.payload(), message.attributes()); + } + } diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java new file mode 100644 index 00000000..3e0319a8 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java @@ -0,0 +1,27 @@ +package org.eclipse.uprotocol.transport.datamodel; + +import org.eclipse.uprotocol.uri.datamodel.UUri; + +/** + * UMessage is the envelop that contains a topic, payload, and attributes. + */ +public interface UMessage { + + /** + * Returns the topic of the message. + * @return Returns the topic of the message. + */ + UUri topic(); + + /** + * The UPayload contains the clean Payload information along with its raw serialized structure of a byte[]. + * @return Returns the UPayload. + */ + UPayload payload(); + + /** + * The UAttributes contains the attributes of the uMessage like ttl, priority, etc... + * @return Returns the UAttributes. + */ + UAttributes attributes(); +} diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java index 1e40625d..00ab8e77 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java @@ -23,9 +23,6 @@ import nl.jqno.equalsverifier.EqualsVerifier; -import org.eclipse.uprotocol.transport.datamodel.UAttributes; -import org.eclipse.uprotocol.transport.datamodel.UMessageType; -import org.eclipse.uprotocol.transport.datamodel.UPriority; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; From 48f782bea8724b8491a892d981aeb05203ec1f4b Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 26 Sep 2023 16:48:28 -0400 Subject: [PATCH 47/52] Revert "Adding uMessage" This reverts commit cc548997f49ea971ae0fccb302ecbdbeb7f3e67a. --- .../datamodel/CloudEventUMessage.java | 38 ------------------- .../uprotocol/transport/UTransport.java | 16 +------- .../transport/datamodel/UListener.java | 15 +------- .../transport/datamodel/UMessage.java | 27 ------------- .../transport/datamodel/UAttributeTest.java | 3 ++ 5 files changed, 5 insertions(+), 94 deletions(-) delete mode 100644 src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java delete mode 100644 src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java b/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java deleted file mode 100644 index 2a2009e3..00000000 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/datamodel/CloudEventUMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.eclipse.uprotocol.cloudevent.datamodel; - -import java.util.Objects; - -import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; -import org.eclipse.uprotocol.transport.datamodel.UAttributes; -import org.eclipse.uprotocol.transport.datamodel.UMessage; -import org.eclipse.uprotocol.transport.datamodel.UPayload; -import org.eclipse.uprotocol.transport.datamodel.USerializationHint; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; -import io.cloudevents.CloudEvent; - -public class CloudEventUMessage implements UMessage { - - private final CloudEvent ce; - - public CloudEventUMessage(CloudEvent ce) { - Objects.requireNonNull(ce, "null CloudEvent"); - this.ce = ce; - } - - @Override - public UUri topic() { - return LongUriSerializer.instance().deserialize(UCloudEvent.getSource(ce)); - } - - @Override - public UPayload payload() { - return new UPayload(UCloudEvent.getPayload(ce).toByteArray(), USerializationHint.PROTOBUF); - } - - @Override - public UAttributes attributes() { - return UAttributes.empty(); - } - -} diff --git a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java index 2c395e1c..674641e1 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java @@ -21,11 +21,8 @@ package org.eclipse.uprotocol.transport; -import java.util.Objects; - import org.eclipse.uprotocol.transport.datamodel.UAttributes; import org.eclipse.uprotocol.transport.datamodel.UListener; -import org.eclipse.uprotocol.transport.datamodel.UMessage; import org.eclipse.uprotocol.transport.datamodel.UPayload; import org.eclipse.uprotocol.transport.datamodel.UStatus; import org.eclipse.uprotocol.uri.datamodel.UEntity; @@ -47,7 +44,7 @@ public interface UTransport { * @return Returns OKSTATUS if authenticate was successful, FAILSTATUS if the calling uE * is not authenticated. */ - UStatus authenticate(UEntity uEntity) ; + UStatus authenticate (UEntity uEntity) ; /** @@ -59,17 +56,6 @@ public interface UTransport { * returns FAILSTATUS with the appropriate failure. */ UStatus send(UUri topic, UPayload payload, UAttributes attributes); - - /** - * Transmit a UMessage object that contains the topic, payload, and UAttributes. - * @param message UMessage object that contains the topic, payload, and UAttributes. - * @return Returns OKSTATUS if the payload has been successfully sent (ACK'ed), otherwise it - * returns FAILSTATUS with the appropriate failure. - */ - default UStatus send(UMessage message) { - Objects.requireNonNull(message); - return send(message.topic(), message.payload(), message.attributes()); - } /** * Register listener to be called when UPayload is received for the specific topic. diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java index 6c93f828..1f1ae760 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java @@ -1,12 +1,9 @@ package org.eclipse.uprotocol.transport.datamodel; -import java.util.Objects; - import org.eclipse.uprotocol.uri.datamodel.UUri; /** - * Listener to receive sent events from the uTransport. The Listeners are registered and - * unregistered through the uTransport API. + * For any implementation that defines some kind of callback or function that will be called to handle incoming messages. */ public interface UListener { @@ -19,14 +16,4 @@ public interface UListener { */ UStatus onReceive(UUri topic, UPayload payload, UAttributes attributes); - /** - * Method called to handle/process events. - * @param message Message received. - * @return Returns an Ack every time a message is received and processed. - */ - default UStatus OnReceive(UMessage message) { - Objects.requireNonNull(message); - return onReceive(message.topic(), message.payload(), message.attributes()); - } - } diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java deleted file mode 100644 index 3e0319a8..00000000 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UMessage.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.eclipse.uprotocol.transport.datamodel; - -import org.eclipse.uprotocol.uri.datamodel.UUri; - -/** - * UMessage is the envelop that contains a topic, payload, and attributes. - */ -public interface UMessage { - - /** - * Returns the topic of the message. - * @return Returns the topic of the message. - */ - UUri topic(); - - /** - * The UPayload contains the clean Payload information along with its raw serialized structure of a byte[]. - * @return Returns the UPayload. - */ - UPayload payload(); - - /** - * The UAttributes contains the attributes of the uMessage like ttl, priority, etc... - * @return Returns the UAttributes. - */ - UAttributes attributes(); -} diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java index 00ab8e77..1e40625d 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java @@ -23,6 +23,9 @@ import nl.jqno.equalsverifier.EqualsVerifier; +import org.eclipse.uprotocol.transport.datamodel.UAttributes; +import org.eclipse.uprotocol.transport.datamodel.UMessageType; +import org.eclipse.uprotocol.transport.datamodel.UPriority; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; From b91e95007b29030cfa6c9f64157d059e6f5a12b2 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Tue, 26 Sep 2023 17:58:00 -0400 Subject: [PATCH 48/52] Cleanup of unused imports and various fixes --- .../validate/UAttributesValidator.java | 6 ++++- .../validate/CloudEventValidatorTest.java | 14 ++++++----- .../transport/datamodel/UAttributeTest.java | 3 --- .../transport/datamodel/UMessageTypeTest.java | 22 +++++++++++++++-- .../transport/datamodel/UPayloadTest.java | 24 ++++++++++++++++--- .../transport/datamodel/UPriorityTest.java | 22 +++++++++++++++-- .../datamodel/USerializationHintTest.java | 22 +++++++++++++++-- .../transport/datamodel/UStatusTest.java | 21 +++++++++++++++- .../validator/UAttributesValidatorTest.java | 5 ++-- .../uri/serializer/LongUriSerializerTest.java | 22 ++++++++++++++++- .../serializer/MicroUriSerializerTest.java | 20 ++++++++++++++++ 11 files changed, 158 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java index 2854b60e..15c5feb3 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java @@ -114,6 +114,10 @@ public UStatus validate(UAttributes attributes) { public UStatus isExpired(UAttributes uAttributes) { try { final Optional maybeTtl = uAttributes.ttl(); + final Optional maybeTime = UUIDUtils.getTime(uAttributes.id()); + if (maybeTime.isEmpty()) { + return UStatus.failed("Invalid Time", Code.INVALID_ARGUMENT); + } if (maybeTtl.isEmpty()) { return UStatus.ok("Not Expired"); } @@ -122,7 +126,7 @@ public UStatus isExpired(UAttributes uAttributes) { return UStatus.ok("Not Expired"); } - long delta = System.currentTimeMillis() - UUIDUtils.getTime(uAttributes.id()); + long delta = System.currentTimeMillis() - maybeTime.get(); return delta >= ttl ? UStatus.failed("Payload is expired", Code.DEADLINE_EXCEEDED) : UStatus.ok("Not Expired"); } catch (Exception e) { diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index 494a0775..e6885047 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -44,6 +44,8 @@ import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; class CloudEventValidatorTest { @@ -1062,10 +1064,10 @@ private Any buildProtoPayloadForTest() { public void test_create_a_v6_cloudevent_and_validate_it_against_sdk() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + UResource.longFormat("door", "front_left", "Door")); + String source = LongUriSerializer.instance().serialize(Uri); UUID uuid = UUIDFactory.Factories.UUIDV6.factory().create(); String id = uuid.toString(); @@ -1093,10 +1095,10 @@ public void test_create_a_v6_cloudevent_and_validate_it_against_sdk() { public void test_create_an_expired_v6_cloudevent() { // source - UEntity use = UEntity.fromName("body.access"); + UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, - new UResource("door", "front_left", "Door")); - String source = UriFactory.buildUProtocolUri(Uri); + UResource.longFormat("door", "front_left", "Door")); + String source = LongUriSerializer.instance().serialize(Uri); UUID uuid = UUIDFactory.Factories.UUIDV6.factory().create(Instant.now().minusSeconds(100)); String id = uuid.toString(); diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java index 1e40625d..00ab8e77 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java @@ -23,9 +23,6 @@ import nl.jqno.equalsverifier.EqualsVerifier; -import org.eclipse.uprotocol.transport.datamodel.UAttributes; -import org.eclipse.uprotocol.transport.datamodel.UMessageType; -import org.eclipse.uprotocol.transport.datamodel.UPriority; import org.eclipse.uprotocol.uri.datamodel.UAuthority; import org.eclipse.uprotocol.uri.datamodel.UEntity; import org.eclipse.uprotocol.uri.datamodel.UResource; diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java index ae576734..3bcfa459 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UMessageTypeTest.java @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.transport.datamodel; import org.junit.jupiter.api.DisplayName; @@ -5,8 +25,6 @@ import static org.junit.jupiter.api.Assertions.*; -import org.eclipse.uprotocol.transport.datamodel.UMessageType; - class UMessageTypeTest { @Test diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java index 9d8f7e9b..65db77e5 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java @@ -1,9 +1,27 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.transport.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; -import org.eclipse.uprotocol.transport.datamodel.UPayload; -import org.eclipse.uprotocol.transport.datamodel.USerializationHint; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -41,7 +59,7 @@ public void testToString() { } @Test - @DisplayName("Create an empty UPyload") + @DisplayName("Create an empty UPayload") public void create_an_empty_upayload() { UPayload uPayload = UPayload.empty(); assertEquals(0, uPayload.data().length); diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java index 9fbaf5e4..19d82087 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPriorityTest.java @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.transport.datamodel; import org.junit.jupiter.api.DisplayName; @@ -6,8 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.eclipse.uprotocol.transport.datamodel.UPriority; - class UPriorityTest { @Test diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java index a246b162..bf25c343 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/USerializationHintTest.java @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.transport.datamodel; import org.junit.jupiter.api.DisplayName; @@ -6,8 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.eclipse.uprotocol.transport.datamodel.USerializationHint; - class USerializationHintTest { @Test diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java index fcfc4868..466a1bd3 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java @@ -1,9 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.transport.datamodel; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; -import org.eclipse.uprotocol.transport.datamodel.UStatus; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java index 70154b1b..a486f425 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java @@ -40,6 +40,7 @@ import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -693,8 +694,8 @@ public void test_validate_uAttributes_for_publish_message_payload_not_expired_ca final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); final UStatus status = validator.isExpired(attributes); - assertTrue(status.isSuccess()); - assertEquals("Not Expired", status.msg()); + assertFalse(status.isSuccess()); + assertEquals("Invalid Time", status.msg()); } // ---- diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index 7b95bec4..89bd73c1 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.uri.serializer; import org.eclipse.uprotocol.uri.datamodel.UUri; @@ -980,7 +1000,7 @@ void test_deserialize_long_and_micro_passing_valid_values() throws UnknownHostEx UResource.resolvedFormat("raise", "salary", "Pay", (short)2)); String longUUri = LongUriSerializer.instance().serialize(uri); byte[] microUUri = MicroUriSerializer.instance().serialize(uri); - UUri notused = UUri.empty(); + Optional uri2 = LongUriSerializer.instance().buildResolved(longUUri, microUUri); assertEquals(uri, uri2.orElse(UUri.empty())); } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java index 92604489..fa2a204d 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2023 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. + */ package org.eclipse.uprotocol.uri.serializer; import static org.junit.jupiter.api.Assertions.assertEquals; From e4f794e58e5063922c7fee006a41f2c21edcec85 Mon Sep 17 00:00:00 2001 From: czfdcn Date: Wed, 27 Sep 2023 08:19:59 -0400 Subject: [PATCH 49/52] Add 100% test coverage --- .../transport/datamodel/UStatusTest.java | 67 +++++++++++++++++++ .../uri/datamodel/UResourceTest.java | 15 ++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java index 466a1bd3..a3787e14 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java @@ -75,6 +75,73 @@ public void testHashCodeEquals_fail_scenarios() { assertEquals(6, statuses.size()); } + + @Test + @DisplayName("Make sure the equals barfs when we compare uStatus that are not the same") + public void testHashCodeEquals_barfs_when_not_same() { + UStatus ok = UStatus.ok(); + UStatus failed = UStatus.failed(); + assertFalse(failed.equals(ok)); + assertFalse(ok.equals(failed)); + } + + @Test + @DisplayName("Test equals when there are differences in message and code") + public void testHashCodeEquals_different_message_and_code() { + UStatus failed = UStatus.failed("boom", UStatus.Code.UNKNOWN); + UStatus failed1 = UStatus.failed("boom", UStatus.Code.INVALID_ARGUMENT); + UStatus failed2 = UStatus.failed("bang", UStatus.Code.UNKNOWN); + UStatus failed3 = UStatus.failed("bang", UStatus.Code.INVALID_ARGUMENT); + assertFalse(failed.equals(failed1)); + assertFalse(failed.equals(failed2)); + assertFalse(failed.equals(failed3)); + + assertFalse(failed1.equals(failed)); + assertFalse(failed1.equals(failed2)); + assertFalse(failed1.equals(failed3)); + + assertFalse(failed2.equals(failed)); + assertFalse(failed2.equals(failed1)); + assertFalse(failed2.equals(failed3)); + + assertFalse(failed3.equals(failed)); + assertFalse(failed3.equals(failed2)); + assertFalse(failed3.equals(failed1)); + } + + @Test + @DisplayName("Make sure the equals is successful when comparing the same failed status") + public void testHashCodeEquals_same_failed_status() { + UStatus failed = UStatus.failed("boom", UStatus.Code.UNKNOWN); + UStatus failed1 = UStatus.failed("boom", UStatus.Code.UNKNOWN); + assertTrue(failed.equals(failed1)); + } + + @Test + @DisplayName("Make sure the equals is successful when comparing the same ok status") + public void testHashCodeEquals_same_ok_status() { + UStatus ok = UStatus.ok(); + UStatus ok1 = UStatus.ok(); + assertTrue(ok.equals(ok1)); + } + + @Test + @DisplayName("Make sure the equals passing the same object is successful") + public void testHashCodeEquals_same_object() { + final UStatus ok = UStatus.ok(); + final UStatus failed = UStatus.failed(); + assertTrue(ok.equals(ok)); + assertTrue(failed.equals(failed)); + } + + @Test + @DisplayName("Make sure the equals passing null reports not equals") + public void testHashCodeEquals_null() { + final UStatus ok = UStatus.ok(); + final UStatus failed = UStatus.failed(); + assertFalse(ok.equals(null)); + assertFalse(failed.equals(null)); + } @Test @DisplayName("Make sure the toString works on ok status") diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java index 3940e620..c8c45ed4 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java @@ -468,5 +468,18 @@ public void test_create_rpc_response() { assertTrue(uResource.isRPCMethod()); } - + @Test + @DisplayName("Test creating invalid uResource with only the message") + public void test_create_invalid_uresource_with_only_message() { + UResource uResource = UResource.resolvedFormat("", null, "Door", null); + assertTrue(uResource.name().isBlank()); + assertTrue(uResource.instance().isEmpty()); + assertFalse(uResource.message().isEmpty()); + assertTrue(uResource.id().isEmpty()); + assertFalse(uResource.isEmpty()); + assertFalse(uResource.isResolved()); + assertFalse(uResource.isLongForm()); + assertFalse(uResource.isMicroForm()); + assertFalse(uResource.isRPCMethod()); + } } \ No newline at end of file From 5bf2bf40bbe2552b355dfc50e8e17690fc42c48e Mon Sep 17 00:00:00 2001 From: czfdcn Date: Thu, 28 Sep 2023 16:39:06 -0400 Subject: [PATCH 50/52] Added back Short URI and finished code coverage --- .../transport/datamodel/UPayload.java | 51 +--- .../datamodel/USerializationHint.java | 5 +- .../validate/UAttributesValidator.java | 40 +-- .../uri/serializer/LongUriSerializer.java | 2 +- .../uri/serializer/MicroUriSerializer.java | 13 +- .../uri/serializer/ShortUriSerializer.java | 199 +++++++++++++ .../uri/serializer/UriSerializer.java | 6 +- .../org/eclipse/uprotocol/rpc/RpcTest.java | 5 +- .../transport/datamodel/UPayloadTest.java | 53 ++-- .../serializer/MicroUriSerializerTest.java | 205 ++++++++++--- .../serializer/ShortUriSerializerTest.java | 276 ++++++++++++++++++ 11 files changed, 695 insertions(+), 160 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java create mode 100644 src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java index 5a72f98b..466710e6 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java @@ -27,15 +27,13 @@ /** * The UPayload contains the clean Payload information along with its raw serialized structure of a byte[]. - */ + */ public class UPayload { - private static final UPayload EMPTY = new UPayload(new byte[0], null); + private static final UPayload EMPTY = new UPayload(new byte[0], USerializationHint.UNKNOWN); private final byte[] data; - private final Integer size; // The size of the payload in bytes - private final USerializationHint hint; // Hint regarding the bytes contained within the UPayload @@ -44,17 +42,8 @@ public class UPayload { * @param data A byte array of the actual data. */ public UPayload(byte[] data, USerializationHint hint) { - this(data, data == null ? 0 : data.length, hint); - } - - /** - * Create a UPayload passing a fixed size - * @param data A byte array of the actual data. - */ - public UPayload(byte[] data, Integer size, USerializationHint hint) { - this.hint = hint; - this.data = data; - this.size = size; + this.data = Objects.requireNonNullElse(data, new byte[0]); + this.hint = Objects.requireNonNullElse(hint, USerializationHint.UNKNOWN); } @@ -63,15 +52,15 @@ public UPayload(byte[] data, Integer size, USerializationHint hint) { * @return Returns the actual serialized or raw data, which can be deserialized or simply used as is. */ public byte[] data() { - return this.data == null ? EMPTY.data() : this.data; + return this.data; } /** * The hint regarding the bytes contained within the UPayload. * @return Returns the hint regarding the bytes contained within the UPayload. */ - public Optional hint() { - return (hint == null) ? Optional.empty() : Optional.of(hint); + public USerializationHint hint() { + return this.hint; } /** @@ -81,29 +70,12 @@ public static UPayload empty() { return EMPTY; } - /** - * Static factory method for creating the payload from a simple String. - * @param payload String payload. - * @param hint Optional hint regarding the bytes contained within the UPayload. - * @return Returns a UPayload from the string argument. - */ - public static UPayload fromString(String payload, USerializationHint hint) { - return new UPayload(payload.getBytes(), hint); - } /** * @return Returns true if the data in the UPayload is empty. */ public boolean isEmpty() { - return this.data == null || this.data.length == 0; - } - - /** - * The size of the payload in bytes - * @return Returns the size of the payload in bytes - */ - public Integer size() { - return size; + return this.data.length == 0; } @@ -112,19 +84,18 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UPayload uPayload = (UPayload) o; - return Arrays.equals(data, uPayload.data) && this.hint == uPayload.hint - && Objects.equals(this.size, uPayload.size); + return Arrays.equals(data, uPayload.data) && this.hint == uPayload.hint; } @Override public int hashCode() { - return Objects.hash(Arrays.hashCode(data),hint, size); + return Objects.hash(Arrays.hashCode(data),hint); } @Override public String toString() { return "UPayload{" + - "data=" + Arrays.toString(data()) + " size=" + size + + "data=" + Arrays.toString(data()) + ", hint=" + hint +'}'; } } diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java index dafce93b..d95c894a 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/USerializationHint.java @@ -38,7 +38,10 @@ public enum USerializationHint { SOMEIP(3, "application/x-someip"), // Raw binary data that has not been serialized - RAW(4, "application/octet-stream"); + RAW(4, "application/octet-stream"), + + // Text Format + TEXT(5, "text/plain"); private final int hintNumber; private final String mimeType; diff --git a/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java index 15c5feb3..986c3474 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java @@ -112,26 +112,22 @@ public UStatus validate(UAttributes attributes) { * @return Returns a {@link UStatus} that is success meaning not expired or failed with a validation message or expiration. */ public UStatus isExpired(UAttributes uAttributes) { - try { - final Optional maybeTtl = uAttributes.ttl(); - final Optional maybeTime = UUIDUtils.getTime(uAttributes.id()); - if (maybeTime.isEmpty()) { - return UStatus.failed("Invalid Time", Code.INVALID_ARGUMENT); - } - if (maybeTtl.isEmpty()) { - return UStatus.ok("Not Expired"); - } - int ttl = maybeTtl.get(); - if (ttl <= 0) { - return UStatus.ok("Not Expired"); - } - - long delta = System.currentTimeMillis() - maybeTime.get(); - - return delta >= ttl ? UStatus.failed("Payload is expired", Code.DEADLINE_EXCEEDED) : UStatus.ok("Not Expired"); - } catch (Exception e) { + final Optional maybeTtl = uAttributes.ttl(); + final Optional maybeTime = UUIDUtils.getTime(uAttributes.id()); + if (maybeTime.isEmpty()) { + return UStatus.failed("Invalid Time", Code.INVALID_ARGUMENT); + } + if (maybeTtl.isEmpty()) { + return UStatus.ok("Not Expired"); + } + int ttl = maybeTtl.get(); + if (ttl <= 0) { return UStatus.ok("Not Expired"); } + + long delta = System.currentTimeMillis() - maybeTime.get(); + + return delta >= ttl ? UStatus.failed("Payload is expired", Code.DEADLINE_EXCEEDED) : UStatus.ok("Not Expired"); } /** @@ -141,12 +137,8 @@ public UStatus isExpired(UAttributes uAttributes) { */ public UStatus validateId(UAttributes attributes) { final UUID id = attributes.id(); - try { - return UUIDUtils.isUuid(id) ? UStatus.ok() : - UStatus.failed(String.format("Invalid UUID [%s]", id), Code.INVALID_ARGUMENT.value()); - } catch (Exception e) { - return UStatus.failed(String.format("Invalid UUID [%s] [%s]", id, e.getMessage()), Code.INVALID_ARGUMENT.value()); - } + return UUIDUtils.isUuid(id) ? UStatus.ok() : + UStatus.failed(String.format("Invalid UUID [%s]", id), Code.INVALID_ARGUMENT.value()); } /** diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index aa675a32..01298265 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -32,7 +32,7 @@ import java.util.stream.Collectors; /** - * UUri Serializer that serializes a UUri to a string (long format) per + * UUri Serializer that serializes a UUri to a long format string per * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc */ public class LongUriSerializer implements UriSerializer { diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index dac13b6e..ff786320 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -81,14 +81,13 @@ public static Optional from(int value) { } /** - * TODO Steven this needs to be fixed * Serialize a UUri into a byte[] following the Micro-URI specifications. * @param Uri The {@link UUri} data object. * @return Returns a byte[] representing the serialized {@link UUri}. */ @Override public byte[] serialize(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { + if (Uri == null || Uri.isEmpty() || !Uri.isMicroForm()) { return new byte[0]; } @@ -96,11 +95,7 @@ public byte[] serialize(UUri Uri) { Optional maybeUeId = Uri.uEntity().id(); Optional maybeUResourceId = Uri.uResource().id(); - // Cannot create a micro URI without UResource ID or uEntity ID - if (maybeUResourceId.isEmpty() || maybeUeId.isEmpty()) { - return new byte[0]; - } - + ByteArrayOutputStream os = new ByteArrayOutputStream(); // UP_VERSION os.write(UP_VERSION); @@ -123,7 +118,7 @@ public byte[] serialize(UUri Uri) { try { os.write(maybeUAuthorityAddressBytes.get()); } catch (IOException e) { - //TODO Steven this is not correct - maybe write an empty byte into the stream + //NOTE: It is impossible for this exception to be thrown as we can never pass invalid address return new byte[0]; } } @@ -196,6 +191,8 @@ else if (addressType == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LE Arrays.copyOfRange(microUri, index, (addressType == AddressType.IPv4) ? 8 : 20)); uAuthority = UAuthority.microRemote(inetAddress); } catch (Exception e) { + // NOTE: It is impossible for this exception to be thrown as we cannot put invalid data in the fixed size + // microUri uAuthority = UAuthority.local(); } index += addressType == AddressType.IPv4 ? 4 : 16; diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java new file mode 100644 index 00000000..fdff236e --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.serializer; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; + +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * UUri Serializer that serializes a UUri to a short format per + * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc + */ +public class ShortUriSerializer implements UriSerializer { + + private static final String SCHEME = "s:"; // Required Scheme + + private static final ShortUriSerializer INSTANCE = new ShortUriSerializer(); + + private ShortUriSerializer(){} + + public static ShortUriSerializer instance() { + return INSTANCE; + } + + /** + * Support for serializing {@link UUri} objects into the short URI format. + * @param Uri {@link UUri} object to be serialized to the short URI format. + * @return Returns the short URI formatted string of the supplied {@link UUri} that can be used as a + * sink or a source in a uProtocol publish communication. + */ + @Override + public String serialize(UUri Uri) { + if (Uri == null || Uri.isEmpty()) { + return ""; + } + + StringBuilder sb = new StringBuilder(SCHEME); + + sb.append(buildAuthorityPartOfUri(Uri.uAuthority())); + + if (Uri.uAuthority().isMarkedRemote()) { + sb.append("/"); + } + + if (Uri.uEntity().isEmpty()) { + return sb.toString(); + } + + sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity())); + + sb.append(buildResourcePartOfUri(Uri.uResource())); + + return sb.toString().replaceAll("/+$", ""); + } + + /** + * Deserialize a Short formatted string into a UUri object. + * @param uProtocolUri A short format uProtocol URI. + * @return Returns an UUri data object. + */ + @Override + public UUri deserialize(String uProtocolUri) { + if (uProtocolUri == null || uProtocolUri.isBlank() || !uProtocolUri.contains(SCHEME)) { + return UUri.empty(); + } + + String uri = uProtocolUri.substring(uProtocolUri.indexOf(":")+1).replace('\\', '/'); + + boolean isLocal = !uri.startsWith("//"); + + final String[] uriParts = uri.split("/"); + final int numberOfPartsInUri = uriParts.length; + + if(numberOfPartsInUri == 0 || numberOfPartsInUri == 1) { + return isLocal ? UUri.empty() : + new UUri(UAuthority.longRemote("", ""), UEntity.empty(), UResource.empty()); + } + + String useName = ""; + String useVersion = ""; + UResource uResource; + UAuthority uAuthority; + String[] authorityParts = uriParts[2].split("\\."); + String device = authorityParts[0]; + String domain = ""; + + if (authorityParts.length > 1) { + domain = Arrays.stream(authorityParts) + .skip(1) + .collect(Collectors.joining(".")); + } + uAuthority = UAuthority.longRemote(device, domain); + + if (uriParts.length > 3) { + useName = uriParts[3]; + if (numberOfPartsInUri > 4) { + useVersion = uriParts[4]; + + if (numberOfPartsInUri > 5) { + try { + Short resourceId = Short.valueOf(uriParts[5]); + uResource = UResource.microFormat(resourceId); + } catch (NumberFormatException ignored) { + return UUri.empty(); + } + } else { + uResource = UResource.empty(); + } + } else { + uResource = UResource.empty(); + } + + } else { + return new UUri(uAuthority, UEntity.empty(), UResource.empty()); + } + + Integer useVersionInt = null; + try { + if (!useVersion.isBlank()) { + useVersionInt = Integer.valueOf(useVersion); + } + } catch (NumberFormatException ignored) { + return UUri.empty(); + } + + Short useId = null; + try { + if (!useName.isBlank()) { + useId = Short.valueOf(useName); + } + } catch (NumberFormatException ignored) { + return UUri.empty(); + } + + return new UUri(uAuthority, UEntity.microFormat(useId, useVersionInt), uResource); + } + + + private static String buildResourcePartOfUri(UResource uResource) { + if (uResource.isEmpty() || !uResource.isMicroForm()) { + return ""; + } + StringBuilder sb = new StringBuilder("/"); + uResource.id().ifPresent(id -> sb.append(id)); + + return sb.toString(); + } + + + private static String buildSoftwareEntityPartOfUri(UEntity use) { + StringBuilder sb = new StringBuilder(); + use.id().ifPresent(sb::append); + sb.append("/"); + use.version().ifPresent(sb::append); + return sb.toString(); + } + + + private static String buildAuthorityPartOfUri(UAuthority Authority) { + if (Authority.isLocal()) { + return "/"; + } + StringBuilder partialURI = new StringBuilder("//"); + final Optional maybeDevice = Authority.device(); + final Optional maybeDomain = Authority.domain(); + + if (maybeDevice.isPresent()) { + partialURI.append(maybeDevice.get()); + maybeDomain.ifPresent(domain -> partialURI.append(".")); + } + maybeDomain.ifPresent(partialURI::append); + + return partialURI.toString(); + } +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index 97e5856e..6c34d4bf 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -29,10 +29,10 @@ import java.util.Optional; /** - * UUris are used in transport layers and hence need to be serialised. - * Each transport supports different serialisation formats. + * UUris are used in transport layers and hence need to be serialized. + * Each transport supports different serialization formats. * For more information, please refer to ... - * @param The data structure that the UUri will be serialised into. For example String or byte[]. + * @param The data structure that the UUri will be serialized into. For example String or byte[]. */ public interface UriSerializer { diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index 2efa0971..ec7bdb06 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -91,7 +91,7 @@ public CompletableFuture invokeMethod(UUri topic, UPayload payload, UA RpcClient ThatBarfsCrapyPayload = new RpcClient() { @Override public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { - UPayload response = new UPayload(new byte[] {0}, null, USerializationHint.RAW); + UPayload response = new UPayload(new byte[] {0}, USerializationHint.RAW); return CompletableFuture.completedFuture(response); } }; @@ -514,8 +514,7 @@ void what_the_stub_looks_like() throws InterruptedException { RpcClient client = new RpcClient() { @Override public CompletableFuture invokeMethod(UUri topic, UPayload payload, UAttributes attributes) { - UPayload data = new UPayload(null, null, null); - return CompletableFuture.completedFuture(data); + return CompletableFuture.completedFuture(UPayload.empty()); } }; diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java index 65db77e5..dc30b19e 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UPayloadTest.java @@ -41,22 +41,10 @@ public void testHashCodeEquals() { @DisplayName("Make sure the toString works on empty") public void testToString_with_empty() { UPayload uPayload = UPayload.empty(); - assertEquals("UPayload{data=[] size=0, hint=null}", uPayload.toString()); + assertEquals("UPayload{data=[], hint=UNKNOWN}", uPayload.toString()); + assertEquals(USerializationHint.UNKNOWN, uPayload.hint()); } - @Test - @DisplayName("Make sure the toString works on null") - public void testToString_with_null() { - UPayload uPayload = new UPayload(null, null); - assertEquals("UPayload{data=[] size=0, hint=null}", uPayload.toString()); - } - - @Test - @DisplayName("Make sure the toString works") - public void testToString() { - UPayload uPayload = UPayload.fromString("hello", null); - assertEquals("UPayload{data=[104, 101, 108, 108, 111] size=5, hint=null}", uPayload.toString()); - } @Test @DisplayName("Create an empty UPayload") @@ -67,43 +55,42 @@ public void create_an_empty_upayload() { } @Test - @DisplayName("Create a UPyload with null") + @DisplayName("Create a UPayload with null") public void create_upayload_with_null() { UPayload uPayload = new UPayload(null, null); assertEquals(0, uPayload.data().length); assertTrue(uPayload.isEmpty()); + assertEquals(USerializationHint.UNKNOWN, uPayload.hint()); } @Test - @DisplayName("Create a UPayload from some bytes") - public void create_upayload_from_bytes() { + @DisplayName("Create a UPayload from string with hint") + public void create_upayload_from_string_with_hint() { String stringData = "hello"; - UPayload uPayload = new UPayload(stringData.getBytes(StandardCharsets.UTF_8), null); + UPayload uPayload = new UPayload(stringData.getBytes(StandardCharsets.UTF_8), USerializationHint.TEXT); assertEquals(stringData.length(), uPayload.data().length); assertFalse(uPayload.isEmpty()); + assertEquals(USerializationHint.TEXT, uPayload.hint()); assertEquals(stringData, new String(uPayload.data())); } @Test - @DisplayName("Create a UPayload from a string") - public void create_upayload_from_a_string() { - String stringData = "hello world"; - UPayload uPayload = UPayload.fromString(stringData, null); + @DisplayName("Create a UPayload from some string without hint") + public void create_upayload_from_string_without_hint() { + String stringData = "hello"; + UPayload uPayload = new UPayload(stringData.getBytes(StandardCharsets.UTF_8), null); assertEquals(stringData.length(), uPayload.data().length); assertFalse(uPayload.isEmpty()); - assertEquals(stringData, new String(uPayload.data())); - assertFalse(uPayload.hint().isPresent()); + assertEquals(USerializationHint.UNKNOWN, uPayload.hint()); } @Test - @DisplayName("Create a UPayload from a string with a hint") - public void create_upayload_from_a_string_with_a_hint() { - String stringData = "hello world"; - UPayload uPayload = UPayload.fromString(stringData, USerializationHint.JSON); - assertEquals(stringData.length(), uPayload.data().length); - assertFalse(uPayload.isEmpty()); - assertEquals(stringData, new String(uPayload.data())); - assertEquals(USerializationHint.JSON, uPayload.hint().get()); + @DisplayName("Create a UPayload without a byte array but with some weird hint") + public void create_upayload_without_byte_array_but_with_weird_hint() { + UPayload uPayload = new UPayload(null, USerializationHint.PROTOBUF); + assertEquals(0, uPayload.data().length); + assertTrue(uPayload.isEmpty()); + assertEquals(USerializationHint.PROTOBUF, uPayload.hint()); + assertFalse(UPayload.empty().equals(uPayload)); } - } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java index fa2a204d..d44257c3 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java @@ -24,6 +24,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; @@ -92,6 +95,20 @@ public void test_serialize_uri_without_version() { assertEquals(uri, uri2); } + @Test + @DisplayName("Test Serialize a remote UUri to micro without the address") + public void test_serialize_remote_uri_without_address() { + UAuthority uAuthority = UAuthority.longRemote("vcu", "vin"); + UEntity use = UEntity.microFormat((short)2, 1); + UResource uResource = UResource.microFormat((short)3); + + UUri uri = new UUri(uAuthority, use, uResource); + + byte[] bytes = MicroUriSerializer.instance().serialize(uri); + assertTrue(bytes.length == 0); + } + + @Test @DisplayName("Test serialize invalid UUris") public void test_serialize_invalid_uuris() { @@ -139,61 +156,155 @@ public void test_serialize_ipv6_uri() throws UnknownHostException { } @Test - @DisplayName("Test deserialize with missing information") - public void test_deserialize_with_missing_information() throws UnknownHostException { - UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UEntity use = UEntity.microFormat((short)2, 1); - UResource uResource = UResource.microFormat((short)3); - UUri uri = new UUri(uAuthority, use, uResource); - byte[] bytes = MicroUriSerializer.instance().serialize(uri); + @DisplayName("Test deserialize with invalid local micro uri") + public void test_deserialize_with_valid_local_uri() { - // invalid version - byte[] byte1 = Arrays.copyOf(bytes, bytes.length); - byte1[0] = 0x0; - UUri uri1 = MicroUriSerializer.instance().deserialize(byte1); - assertTrue(uri1.isEmpty()); - - // Invalid type - byte[] byte2 = Arrays.copyOf(bytes, bytes.length); - byte2[1] = Byte.MAX_VALUE; - UUri uri2 = MicroUriSerializer.instance().deserialize(byte2); - assertTrue(uri2.isEmpty()); - - // Wrong size (local) - byte[] byte3 = new byte[] {0x1, 0x0, 0x0, 0x0}; - UUri uri3 = MicroUriSerializer.instance().deserialize(byte3); - assertTrue(uri3.isEmpty()); + byte[] bytes = {0x1, 0x0, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertFalse(uri.isEmpty()); + assertTrue(uri.isMicroForm()); + assertFalse(uri.isResolved()); + assertFalse(uri.isLongForm()); + assertTrue(uri.uAuthority().isLocal()); + assertTrue(uri.uEntity().version().isPresent()); + assertEquals(uri.uEntity().version().get(),(short)1); + assertTrue(uri.uEntity().id().isPresent()); + assertEquals(uri.uEntity().id().get(), (short)2); + assertTrue(uri.uResource().id().isPresent()); + assertEquals(uri.uResource().id().get(), (short)5); + } - // Wrong size (ipv4) - byte[] byte4 = new byte[] {0x1, 0x1, 0x0, 0x0}; - UUri uri4 = MicroUriSerializer.instance().deserialize(byte4); - assertTrue(uri4.isEmpty()); + @Test + @DisplayName("Test deserialize with valid IPv4 micro uri") + public void test_deserialize_with_valid_ipv4_uri() { + + byte[] bytes = {0x1, 0x1, 0x0, 0x5, (byte)192, (byte)168, 1, (byte)100, 0x0, 0x2, 0x1, 0x0}; + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertFalse(uri.isEmpty()); + assertTrue(uri.isMicroForm()); + assertFalse(uri.isResolved()); + assertFalse(uri.isLongForm()); + assertTrue(uri.uAuthority().isRemote()); + assertTrue(uri.uEntity().version().isPresent()); + assertEquals(uri.uEntity().version().get(),(short)1); + assertTrue(uri.uEntity().id().isPresent()); + assertEquals(uri.uEntity().id().get(), (short)2); + assertTrue(uri.uResource().id().isPresent()); + assertEquals(uri.uResource().id().get(), (short)5); + assertTrue(uri.uAuthority().address().isPresent()); + try { + assertEquals(uri.uAuthority().address().get(), Inet4Address.getByName("192.168.1.100")); + } catch (UnknownHostException e) { + assertTrue(false); + } + } - // Wrong size (ipv6) - byte[] byte5 = new byte[] {0x1, 0x1, 0x0, 0x0}; - UUri uri5 = MicroUriSerializer.instance().deserialize(byte5); - assertTrue(uri5.isEmpty()); + @Test + @DisplayName("Test deserialize with valid IPv6 micro uri") + public void test_deserialize_with_valid_ipv6_uri() { + try { + InetAddress ipv6 = InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"); + byte[] ipv6Bytes = ipv6.getAddress(); + + byte[] header = {0x1, 0x2, 0x0, 0x5}; + byte[] footer = {0x0, 0x2, 0x1, 0x0}; + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(header); + outputStream.write(ipv6Bytes); + outputStream.write(footer); + + byte[] bytes = outputStream.toByteArray(); + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertFalse(uri.isEmpty()); + assertTrue(uri.isMicroForm()); + assertFalse(uri.isResolved()); + assertFalse(uri.isLongForm()); + assertTrue(uri.uAuthority().isRemote()); + assertTrue(uri.uEntity().version().isPresent()); + assertEquals(uri.uEntity().version().get(),(short)1); + assertTrue(uri.uEntity().id().isPresent()); + assertEquals(uri.uEntity().id().get(), (short)2); + assertTrue(uri.uResource().id().isPresent()); + assertEquals(uri.uResource().id().get(), (short)5); + assertTrue(uri.uAuthority().address().isPresent()); + assertEquals(uri.uAuthority().address().get(), ipv6); + } catch (Exception e) { + assertTrue(false); + } + } - // Right local size (local) - byte[] byte6 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri6 = MicroUriSerializer.instance().deserialize(byte6); - assertFalse(uri6.isEmpty()); + @Test + @DisplayName("Test deserialize with invalid version") + public void test_deserialize_with_invalid_version() { + byte[] bytes = {0x9, 0x0, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertTrue(uri.isEmpty()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); + } - // IPv4 type local size - byte[] byte7 = new byte[] {0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri7 = MicroUriSerializer.instance().deserialize(byte7); - assertTrue(uri7.isEmpty()); + @Test + @DisplayName("Test deserialize with invalid type") + public void test_deserialize_with_invalid_type() { + byte[] bytes = {0x1, 0x9, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertTrue(uri.isEmpty()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); + } - // IPv6 type local size - byte[] byte8 = new byte[] {0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri8 = MicroUriSerializer.instance().deserialize(byte8); - assertTrue(uri8.isEmpty()); + @Test + @DisplayName("Test deserialize with wrong size for local micro URI") + public void test_deserialize_with_wrong_size_for_local_micro_uri() { + byte[] bytes = {0x1, 0x0, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0, 0x0}; + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertTrue(uri.isEmpty()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); + } + @Test + @DisplayName("Test deserialize with wrong size for IPv4 micro URI") + public void test_deserialize_with_wrong_size_for_ipv4_micro_uri() { + byte[] bytes = {0x1, 0x1, 0x0, 0x5, (byte)192, (byte)168, 1, (byte)100, 0x0, 0x2, 0x1, 0x0, 0x0}; + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertTrue(uri.isEmpty()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); + } - // Local type but too large - byte[] byte9 = new byte[] {0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - UUri uri9 = MicroUriSerializer.instance().deserialize(byte9); - assertTrue(uri9.isEmpty()); + @Test + @DisplayName("Test deserialize with wrong size for IPv6 micro URI") + public void test_deserialize_with_wrong_size_for_ipv6_micro_uri() { + try { + byte[] ipv6Bytes = new byte[30]; + + byte[] header = {0x1, 0x2, 0x0, 0x5}; + byte[] footer = {0x0, 0x2, 0x1, 0x0}; + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(header); + outputStream.write(ipv6Bytes); + outputStream.write(footer); + + byte[] bytes = outputStream.toByteArray(); + + UUri uri = MicroUriSerializer.instance().deserialize(bytes); + assertTrue(uri.isEmpty()); + assertFalse(uri.isMicroForm()); + assertFalse(uri.isResolved()); + } catch (Exception e) { + assertTrue(false); + } } + } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java new file mode 100644 index 00000000..921ac106 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2023 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. + */ +package org.eclipse.uprotocol.uri.serializer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.eclipse.uprotocol.uri.datamodel.UAuthority; +import org.eclipse.uprotocol.uri.datamodel.UEntity; +import org.eclipse.uprotocol.uri.datamodel.UResource; +import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ShortUriSerializerTest { + @Test + @DisplayName("Test serialize empty UUri") + public void test_serialize_empty_uuri() { + final String strUri = ShortUriSerializer.instance().serialize(UUri.empty()); + assertEquals("", strUri); + } + + @Test + @DisplayName("Test serialize null UUri") + public void test_serialize_null_uuri() { + final String strUri = ShortUriSerializer.instance().serialize(null); + assertEquals("", strUri); + } + + @Test + @DisplayName("Test serialize Resolved local UUri") + public void test_serialize_resolved_local_uuri() { + final UEntity uEntity = UEntity.resolvedFormat("hartley", 1, (short)2); + final UResource uResource = UResource.resolvedFormat("salary", "raise", "Salary", (short)4); + final UUri uri = new UUri(UAuthority.local(), uEntity, uResource); + final String strUri = ShortUriSerializer.instance().serialize(uri); + assertFalse(strUri.isEmpty()); + assertEquals("s:/2/1/4", strUri); + } + + @Test + @DisplayName("Test serialize Resolved remote UUri") + public void test_serialize_resolved_remote_uuri() { + final UAuthority uAuthority = UAuthority.longRemote("vcu", "vin"); + final UEntity uEntity = UEntity.resolvedFormat("hartley", 1, (short)2); + final UResource uResource = UResource.resolvedFormat("salary", "raise", "Salary", (short)4); + final UUri uri = new UUri(uAuthority, uEntity, uResource); + final String strUri = ShortUriSerializer.instance().serialize(uri); + assertFalse(strUri.isEmpty()); + assertEquals("s://vcu.vin/2/1/4", strUri); + } + + @Test + @DisplayName("Test serialize with empty authority names") + public void test_serialize_missing_authority_names() { + final UAuthority uAuthority = UAuthority.longRemote("", ""); + final UEntity uEntity = UEntity.microFormat((short)2, 1); + final UResource uResource = UResource.microFormat((short)4); + final UUri uri = new UUri(uAuthority, uEntity, uResource); + final String strUri = ShortUriSerializer.instance().serialize(uri); + assertEquals("s:///2/1/4", strUri); + } + + @Test + @DisplayName("Test serialize with empty UEntity") + public void test_serialize_empty_uentity() { + final UAuthority uAuthority = UAuthority.local(); + final UEntity uEntity = UEntity.empty(); + final UResource uResource = UResource.microFormat((short)4); + final UUri uri = new UUri(uAuthority, uEntity, uResource); + final String strUri = ShortUriSerializer.instance().serialize(uri); + assertEquals("s:/", strUri); + } + + @Test + @DisplayName("Test serialize with empty UResource") + public void test_serialize_empty_uresource() { + final UAuthority uAuthority = UAuthority.local(); + final UEntity uEntity = UEntity.microFormat((short)2, 1); + final UResource uResource = UResource.empty(); + final UUri uri = new UUri(uAuthority, uEntity, uResource); + final String strUri = ShortUriSerializer.instance().serialize(uri); + assertEquals("s:/2/1", strUri); + } + + @Test + @DisplayName("Test serialize with UResource that is missing uresource id") + public void test_serialize_missing_uresource_id() { + final UAuthority uAuthority = UAuthority.local(); + final UEntity uEntity = UEntity.microFormat((short)2, 1); + final UResource uResource = UResource.longFormat("raise"); + final UUri uri = new UUri(uAuthority, uEntity, uResource); + final String strUri = ShortUriSerializer.instance().serialize(uri); + assertEquals("s:/2/1", strUri); + } + + @Test + @DisplayName("Test deserialize null string") + public void test_deserialize_null_string() { + final UUri uri = ShortUriSerializer.instance().deserialize(null); + assertEquals(UUri.empty(), uri); + } + + @Test + @DisplayName("Test deserialize empty string") + public void test_deserialize_empty_string() { + final UUri uri = ShortUriSerializer.instance().deserialize(""); + assertEquals(UUri.empty(), uri); + } + + @Test + @DisplayName("Test deserialize string with no slashes") + public void test_deserialize_string_with_no_slashes() { + final UUri uri = ShortUriSerializer.instance().deserialize("abc"); + assertEquals(UUri.empty(), uri); + } + + @Test + @DisplayName("Test deserialize string with one slash") + public void test_deserialize_string_with_one_slash() { + final UUri uri = ShortUriSerializer.instance().deserialize("s:/"); + assertEquals(UUri.empty(), uri); + } + + @Test + @DisplayName("Test deserialize string with two slashes") + public void test_deserialize_string_with_two_slashes() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://"); + assertTrue(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + } + + @Test + @DisplayName("Test deserialize string with three slashes") + public void test_deserialize_string_with_three_slashes() { + final UUri uri = ShortUriSerializer.instance().deserialize("s:///"); + assertTrue(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + } + + @Test + @DisplayName("Test deserialize string with four slashes") + public void test_deserialize_string_with_four_slashes() { + final UUri uri = ShortUriSerializer.instance().deserialize("s:////"); + assertTrue(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + } + + + @Test + @DisplayName("Test deserialize string with without any parts") + public void test_deserialize_string_without_any_parts() { + final UUri uri = ShortUriSerializer.instance().deserialize("s:"); + assertTrue(uri.isEmpty()); + } + + + @Test + @DisplayName("Test deserialize string with only device part of authority and no entity or resource") + public void test_deserialize_string_with_only_device_part_ofauthority_and_no_entity_or_resource() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu"); + assertFalse(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + assertEquals("vcu", uri.uAuthority().device().orElse("")); + assertFalse(uri.uAuthority().domain().isPresent()); + assertTrue(uri.uEntity().isEmpty()); + assertTrue(uri.uResource().isEmpty()); + } + @Test + @DisplayName("Test deserialize string with authority and no entity or resource") + public void test_deserialize_string_with_authority_and_no_entity_or_resource() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin"); + assertFalse(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + assertEquals("vcu", uri.uAuthority().device().orElse("")); + assertEquals("vin", uri.uAuthority().domain().orElse("")); + assertTrue(uri.uEntity().isEmpty()); + assertTrue(uri.uResource().isEmpty()); + } + + @Test + @DisplayName("Test deserialize string with authority and entity and no resource") + public void test_deserialize_string_with_authority_and_entity_and_no_resource() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2/1"); + assertFalse(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + assertEquals("vcu", uri.uAuthority().device().orElse("")); + assertEquals("vin", uri.uAuthority().domain().orElse("")); + assertFalse(uri.uEntity().isEmpty()); + assertEquals((short)2, uri.uEntity().id().orElse((short)0)); + assertEquals(1, uri.uEntity().version().orElse(0)); + assertTrue(uri.uResource().isEmpty()); + } + + @Test + @DisplayName("Test deserialize string with authority and missing UEntity but with uResource") + public void test_deserialize_string_with_authority_and_missing_entity_with_resource() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin///2"); + assertFalse(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + assertEquals("vcu", uri.uAuthority().device().orElse("")); + assertEquals("vin", uri.uAuthority().domain().orElse("")); + assertTrue(uri.uEntity().isEmpty()); + assertFalse(uri.uResource().isEmpty()); + assertTrue(uri.uResource().id().isPresent()); + assertEquals(uri.uResource().id().get(), (short)2); + } + + @Test + @DisplayName("Test deserialize remote string without scheme") + public void test_deserialize_remote_string_without_scheme() { + final UUri uri = ShortUriSerializer.instance().deserialize("//vcu.vin/2/1/2"); + assertTrue(uri.isEmpty()); + } + + @Test + @DisplayName("Test deserialize local string without scheme") + public void test_deserialize_local_string_without_scheme() { + final UUri uri = ShortUriSerializer.instance().deserialize("/2/1/2"); + assertTrue(uri.isEmpty()); + } + + @Test + @DisplayName("Test deserialize remote string with UEntity id but missing UEntity version") + public void test_deserialize_remote_string_with_uentityid_without_version() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2"); + assertFalse(uri.isEmpty()); + assertTrue(uri.uAuthority().isMarkedRemote()); + assertEquals("vcu", uri.uAuthority().device().orElse("")); + assertEquals("vin", uri.uAuthority().domain().orElse("")); + assertFalse(uri.uEntity().isEmpty()); + assertEquals((short)2, uri.uEntity().id().orElse((short)0)); + assertTrue(uri.uResource().isEmpty()); + } + + @Test + @DisplayName("Test deserialize string with invalid uEntity_id") + public void test_deserialize_string_with_invalid_uentity_id() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/abc/1/2"); + assertTrue(uri.isEmpty()); + } + + @Test + @DisplayName("Test deserialize string with invalid uEntity_version") + public void test_deserialize_string_with_invalid_uentity_version() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2/abc/2"); + assertTrue(uri.isEmpty()); + } + + @Test + @DisplayName("Test deserialize string with invalid uResource_id") + public void test_deserialize_string_with_invalid_uresource_id() { + final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2/1/abc"); + assertTrue(uri.isEmpty()); + } + +} From 4b34d011a9e503636bf96b734fceda949859a48d Mon Sep 17 00:00:00 2001 From: czfdcn Date: Fri, 20 Oct 2023 09:05:41 -0400 Subject: [PATCH 51/52] Update Micro Uri Format The IP address moved to the end of the Micro URI format --- .../uri/serializer/MicroUriSerializer.java | 42 +++++++++---------- .../serializer/MicroUriSerializerTest.java | 15 +++---- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index ff786320..4d49f9fc 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -112,17 +112,6 @@ public byte[] serialize(UUri Uri) { os.write(maybeUResourceId.get()>>8); os.write(maybeUResourceId.get()); - // UAUTHORITY_ADDRESS - final Optional maybeUAuthorityAddressBytes = calculateUAuthorityBytes(Uri.uAuthority()); - if (maybeUAuthorityAddressBytes.isPresent()) { - try { - os.write(maybeUAuthorityAddressBytes.get()); - } catch (IOException e) { - //NOTE: It is impossible for this exception to be thrown as we can never pass invalid address - return new byte[0]; - } - } - // UENTITY_ID os.write(maybeUeId.get()>>8); os.write(maybeUeId.get()); @@ -134,6 +123,17 @@ public byte[] serialize(UUri Uri) { // UNUSED os.write((byte)0); + // UAUTHORITY_ADDRESS + final Optional maybeUAuthorityAddressBytes = calculateUAuthorityBytes(Uri.uAuthority()); + if (maybeUAuthorityAddressBytes.isPresent()) { + try { + os.write(maybeUAuthorityAddressBytes.get()); + } catch (IOException e) { + //NOTE: It is impossible for this exception to be thrown as we can never pass invalid address + return new byte[0]; + } + } + return os.toByteArray(); } @@ -180,33 +180,31 @@ else if (addressType == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LE return UUri.empty(); } + // UENTITY_ID + int ueId = ((microUri[4] & 0xFF) << 8) | (microUri[5] & 0xFF); + + // UE_VERSION + int uiVersion = microUri[6]; + // Calculate uAuthority UAuthority uAuthority; - int index = 4; if (addressType == AddressType.LOCAL) { uAuthority = UAuthority.local(); } else { try { final InetAddress inetAddress = InetAddress.getByAddress( - Arrays.copyOfRange(microUri, index, (addressType == AddressType.IPv4) ? 8 : 20)); + Arrays.copyOfRange(microUri, 8, (addressType == AddressType.IPv4) ? + IPV4_MICRO_URI_LENGTH : IPV6_MICRO_URI_LENGTH)); uAuthority = UAuthority.microRemote(inetAddress); } catch (Exception e) { // NOTE: It is impossible for this exception to be thrown as we cannot put invalid data in the fixed size // microUri uAuthority = UAuthority.local(); } - index += addressType == AddressType.IPv4 ? 4 : 16; } - - // UENTITY_ID - int ueId = ((microUri[index++] & 0xFF) << 8) | (microUri[index++] & 0xFF); - - // UE_VERSION - int uiVersion = microUri[index]; - return new UUri(uAuthority, UEntity.microFormat((short)ueId, uiVersion == 0 ? null : uiVersion), UResource.microFormat((short)uResourceId)); - } + } } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java index d44257c3..1855f705 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java @@ -179,7 +179,7 @@ public void test_deserialize_with_valid_local_uri() { @DisplayName("Test deserialize with valid IPv4 micro uri") public void test_deserialize_with_valid_ipv4_uri() { - byte[] bytes = {0x1, 0x1, 0x0, 0x5, (byte)192, (byte)168, 1, (byte)100, 0x0, 0x2, 0x1, 0x0}; + byte[] bytes = {0x1, 0x1, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0, (byte)192, (byte)168, 1, (byte)100}; UUri uri = MicroUriSerializer.instance().deserialize(bytes); assertFalse(uri.isEmpty()); @@ -208,13 +208,11 @@ public void test_deserialize_with_valid_ipv6_uri() { InetAddress ipv6 = InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"); byte[] ipv6Bytes = ipv6.getAddress(); - byte[] header = {0x1, 0x2, 0x0, 0x5}; - byte[] footer = {0x0, 0x2, 0x1, 0x0}; + byte[] header = {0x1, 0x2, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); outputStream.write(header); outputStream.write(ipv6Bytes); - outputStream.write(footer); byte[] bytes = outputStream.toByteArray(); @@ -273,7 +271,7 @@ public void test_deserialize_with_wrong_size_for_local_micro_uri() { @Test @DisplayName("Test deserialize with wrong size for IPv4 micro URI") public void test_deserialize_with_wrong_size_for_ipv4_micro_uri() { - byte[] bytes = {0x1, 0x1, 0x0, 0x5, (byte)192, (byte)168, 1, (byte)100, 0x0, 0x2, 0x1, 0x0, 0x0}; + byte[] bytes = {0x1, 0x1, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0, 0x0, (byte)192, (byte)168, 1, (byte)100}; UUri uri = MicroUriSerializer.instance().deserialize(bytes); assertTrue(uri.isEmpty()); @@ -287,13 +285,11 @@ public void test_deserialize_with_wrong_size_for_ipv6_micro_uri() { try { byte[] ipv6Bytes = new byte[30]; - byte[] header = {0x1, 0x2, 0x0, 0x5}; - byte[] footer = {0x0, 0x2, 0x1, 0x0}; + byte[] header = {0x1, 0x2, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); outputStream.write(header); outputStream.write(ipv6Bytes); - outputStream.write(footer); byte[] bytes = outputStream.toByteArray(); @@ -305,6 +301,5 @@ public void test_deserialize_with_wrong_size_for_ipv6_micro_uri() { assertTrue(false); } } - - + } From b03bf9a26811c562dbb6ccc5e1bd45fe779e4edf Mon Sep 17 00:00:00 2001 From: Steven Hartley Date: Tue, 31 Oct 2023 19:40:46 -0400 Subject: [PATCH 52/52] 1.5 uuri (#28) * Staging on the server the 1.5 datamodel move * Merge in of lots more changes --- pom.xml | 38 +- .../cloudevent/factory/CloudEventFactory.java | 2 +- .../validate/CloudEventValidator.java | 34 +- .../org/eclipse/uprotocol/rpc/RpcClient.java | 2 +- .../uprotocol/transport/UTransport.java | 4 +- .../transport/datamodel/UAttributes.java | 30 +- .../transport/datamodel/UListener.java | 2 +- .../transport/datamodel/UPayload.java | 1 - .../validate/UAttributesValidator.java | 144 ++-- .../uri/builder/UResourceBuilder.java | 32 + .../uprotocol/uri/datamodel/UAuthority.java | 246 ------- .../uprotocol/uri/datamodel/UEntity.java | 204 ----- .../uprotocol/uri/datamodel/UResource.java | 261 ------- .../eclipse/uprotocol/uri/datamodel/UUri.java | 171 ----- .../uprotocol/uri/datamodel/UriFormat.java | 33 - .../uri/serializer/LongUriSerializer.java | 141 ++-- .../uri/serializer/MicroUriSerializer.java | 144 ++-- .../uri/serializer/ShortUriSerializer.java | 199 ----- .../uri/serializer/UriSerializer.java | 46 +- .../uprotocol/uri/validator/UriValidator.java | 137 +++- .../uuid/validate/UuidValidator.java | 2 +- .../ValidationResult.java | 2 +- .../factory/CloudEventFactoryTest.java | 199 +---- .../cloudevent/factory/UCloudEventTest.java | 21 +- .../CloudEventToJsonSerializerTest.java | 12 +- .../CloudEventToProtobufSerializerTest.java | 29 +- .../validate/CloudEventValidatorTest.java | 573 +-------------- .../validate/ValidationResultTest.java | 6 +- .../org/eclipse/uprotocol/rpc/RpcTest.java | 8 +- .../transport/datamodel/UAttributeTest.java | 124 ++-- .../transport/datamodel/UStatusTest.java | 4 +- .../validator/UAttributesValidatorTest.java | 458 ++++++------ .../uri/datamodel/UAuthorityTest.java | 308 -------- .../uprotocol/uri/datamodel/UEntityTest.java | 291 -------- .../uri/datamodel/UResourceTest.java | 485 ------------ .../uprotocol/uri/datamodel/UUriTest.java | 298 -------- .../uri/serializer/LongUriSerializerTest.java | 695 +++++++++--------- .../serializer/MicroUriSerializerTest.java | 261 +------ .../serializer/ShortUriSerializerTest.java | 276 ------- .../uri/validator/UUriValidatorTest.java | 151 ---- .../uri/validator/UriValidatorTest.java | 513 +++++++++++++ .../eclipse/uprotocol/uri/validator/uris.json | 38 + .../uuid/validator/UuidValidatorTest.java | 3 +- 43 files changed, 1783 insertions(+), 4845 deletions(-) create mode 100644 src/main/java/org/eclipse/uprotocol/uri/builder/UResourceBuilder.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java delete mode 100644 src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java rename src/main/java/org/eclipse/uprotocol/{cloudevent/validate => validation}/ValidationResult.java (98%) delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java delete mode 100644 src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java create mode 100644 src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java create mode 100644 src/test/java/org/eclipse/uprotocol/uri/validator/uris.json diff --git a/pom.xml b/pom.xml index 8538dbe4..e4119d0f 100644 --- a/pom.xml +++ b/pom.xml @@ -132,6 +132,27 @@ + + + io.cloudevents + cloudevents-protobuf + 2.4.2 + + + + + com.google.errorprone + error_prone_annotations + 2.11.0 + + + + + org.checkerframework + checker-qual + 3.12.0 + + com.google.protobuf protobuf-bom @@ -189,7 +210,7 @@ io.cloudevents cloudevents-protobuf - 2.2.0 + @@ -224,14 +245,6 @@ - - com.google.truth.extensions - truth-proto-extension - 1.1 - test - - - com.github.f4b6a3 @@ -244,6 +257,13 @@ commons-validator 1.7 + + org.eclipse.uprotocol + uprotocol-core-api + 1.4.9-SNAPSHOT + system + ${project.basedir}/uprotocol-core-api-1.4.9-SNAPSHOT.jar + diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java b/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java index 7ebe31a1..b7c6e545 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.java @@ -23,7 +23,7 @@ import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; -import org.eclipse.uprotocol.uri.datamodel.UUri; + import com.google.protobuf.Any; import com.google.protobuf.Empty; import com.google.rpc.Code; diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java index 8001ee24..95cd593d 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java +++ b/src/main/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.java @@ -26,10 +26,11 @@ import io.cloudevents.CloudEvent; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.validation.ValidationResult; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; +import org.eclipse.uprotocol.uri.validator.UriValidator; import java.util.Optional; import java.util.stream.Collectors; @@ -156,19 +157,10 @@ public static ValidationResult validateUEntityUri(String uri) { } public static ValidationResult validateUEntityUri(UUri Uri) { - final UAuthority uAuthority = Uri.uAuthority(); - if (uAuthority.isMarkedRemote()) { - if (uAuthority.device().isEmpty()) { - return ValidationResult.failure("UriPart is configured to be microRemote and is missing uAuthority device name."); - } - } - if (Uri.uEntity().name().isBlank()) { - return ValidationResult.failure("UriPart is missing uSoftware Entity name."); - } - return ValidationResult.success(); + return UriValidator.validate(Uri); } - /** +/** * Validate a UriPart that is to be used as a topic in publish scenarios for events such as publish, file and notification. * @param uri String UriPart to validate. * @return Returns the ValidationResult containing a success or a failure with the error message. @@ -188,11 +180,11 @@ public static ValidationResult validateTopicUri(UUri Uri) { if (validationResult.isFailure()) { return validationResult; } - final UResource uResource = Uri.uResource(); - if (uResource.name().isBlank()) { + final UResource uResource = Uri.getResource(); + if (uResource.getName().isBlank()) { return ValidationResult.failure("UriPart is missing uResource name."); } - if (uResource.message().isEmpty()) { + if (uResource.getMessage().isEmpty()) { return ValidationResult.failure("UriPart is missing Message information."); } return ValidationResult.success(); @@ -219,8 +211,8 @@ public static ValidationResult validateRpcTopicUri(UUri Uri) { if (validationResult.isFailure()){ return ValidationResult.failure(String.format("Invalid RPC uri application response topic. %s", validationResult.getMessage())); } - final UResource uResource = Uri.uResource(); - String topic = String.format("%s.%s", uResource.name(), uResource.instance().isPresent() ? uResource.instance().get() : "" ); + final UResource uResource = Uri.getResource(); + String topic = String.format("%s.%s", uResource.getName(), uResource.getInstance()); if (!"rpc.response".equals(topic)) { return ValidationResult.failure("Invalid RPC uri application response topic. UriPart is missing rpc.response."); } @@ -238,8 +230,8 @@ public static ValidationResult validateRpcMethod(String uri) { if (validationResult.isFailure()){ return ValidationResult.failure(String.format("Invalid RPC method uri. %s", validationResult.getMessage())); } - final UResource uResource = Uri.uResource(); - if (!uResource.isRPCMethod()) { + + if (!UriValidator.isRpcMethod(Uri)) { return ValidationResult.failure("Invalid RPC method uri. UriPart should be the method to be called, or method from response."); } return ValidationResult.success(); diff --git a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java index c9add775..78a6c592 100644 --- a/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java +++ b/src/main/java/org/eclipse/uprotocol/rpc/RpcClient.java @@ -25,7 +25,7 @@ import org.eclipse.uprotocol.transport.datamodel.UAttributes; import org.eclipse.uprotocol.transport.datamodel.UPayload; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.v1.UUri; /** * RpcClient is an interface used by code generators for uProtocol services defined in proto files such as diff --git a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java index 674641e1..675dc27d 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/UTransport.java +++ b/src/main/java/org/eclipse/uprotocol/transport/UTransport.java @@ -25,8 +25,8 @@ import org.eclipse.uprotocol.transport.datamodel.UListener; import org.eclipse.uprotocol.transport.datamodel.UPayload; import org.eclipse.uprotocol.transport.datamodel.UStatus; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UUri; /** * UTransport is the uP-L1 interface that provides a common API for uE developers to send and receive messages. diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java index 21727517..143d267a 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UAttributes.java @@ -25,10 +25,7 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.v1.UUri; /** * When sending data over uTransport the basic API for send uses a source topic and the UPayload as the data. @@ -108,18 +105,6 @@ public static UAttributesBuilder forRpcRequest(UUID id, UUri sink) { .withSink(sink); } - /** - * Static factory method for creating a base UAttributes for an RPC request. - * @param id Unique identifier for the RPC request message. - * @param uAuthority Indicates where the software for RPC request is installed. - * @param serviceUEntity Indicates what service we want to RPC request to change. - * @param commandName String command name the RPC is executing. - * @return Returns a base UAttributes that can be used to build an RPC request. - */ - public static UAttributesBuilder forRpcRequest(UUID id, UAuthority uAuthority, UEntity serviceUEntity, String commandName) { - return new UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(new UUri(uAuthority, serviceUEntity, UResource.forRpcRequest(commandName))); - } /** * Static factory method for creating a base UAttributes for an RPC response. @@ -134,19 +119,6 @@ public static UAttributesBuilder forRpcResponse(UUID id, UUri sink, UUID request .withReqId(requestId); } - /** - * Static factory method for creating a base UAttributes for an RPC response. - * @param id Unique identifier for the RPC response message. - * @param uAuthority Indicates where the software for RPC response is for is installed. - * @param callerUEntity Indicates what service called the RPC request and this response is for. - * @param requestId The id of the RPC request that this message is responding to. - * @return Returns a base UAttributes that can be used to build an RPC response. - */ - public static UAttributesBuilder forRpcResponse(UUID id, UAuthority uAuthority, UEntity callerUEntity, UUID requestId) { - return new UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(new UUri(uAuthority, callerUEntity, UResource.forRpcResponse())) - .withReqId(requestId); - } /** * Unique identifier for the message. diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java index 1f1ae760..33f80bdb 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UListener.java @@ -1,6 +1,6 @@ package org.eclipse.uprotocol.transport.datamodel; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.v1.UUri; /** * For any implementation that defines some kind of callback or function that will be called to handle incoming messages. diff --git a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java index 466710e6..c73342d7 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java +++ b/src/main/java/org/eclipse/uprotocol/transport/datamodel/UPayload.java @@ -23,7 +23,6 @@ import java.util.Arrays; import java.util.Objects; -import java.util.Optional; /** * The UPayload contains the clean Payload information along with its raw serialized structure of a byte[]. diff --git a/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java index 986c3474..4aab1ae4 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/transport/validate/UAttributesValidator.java @@ -27,6 +27,8 @@ import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.uuid.factory.UUIDUtils; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.validation.ValidationResult; import java.util.Optional; import java.util.UUID; @@ -86,10 +88,10 @@ public UAttributesValidator validator() { /** * Take a {@link UAttributes} object and run validations. * @param attributes The UAttriubes to validate. - * @return Returns a {@link UStatus} that is success or failed with a message containing all validation errors for + * @return Returns a {@link ValidationResult} that is success or failed with a message containing all validation errors for * invalid configurations. */ - public UStatus validate(UAttributes attributes) { + public ValidationResult validate(UAttributes attributes) { final String errorMessage = Stream.of( validateId(attributes), validateType(attributes), @@ -99,122 +101,122 @@ public UStatus validate(UAttributes attributes) { validateCommStatus(attributes), validatePermissionLevel(attributes), validateReqId(attributes)) - .filter(UStatus::isFailed) - .map(UStatus::msg) + .filter(ValidationResult::isFailure) + .map(ValidationResult::getMessage) .collect(Collectors.joining(",")); - return errorMessage.isBlank() ? UStatus.ok() : - UStatus.failed(errorMessage, Code.INVALID_ARGUMENT); + return errorMessage.isBlank() ? ValidationResult.success() : + ValidationResult.failure(errorMessage); } /** * Indication if the Payload with these UAttributes is expired. * @param uAttributes UAttributes with time to live value. - * @return Returns a {@link UStatus} that is success meaning not expired or failed with a validation message or expiration. + * @return Returns a {@link ValidationResult} that is success meaning not expired or failed with a validation message or expiration. */ - public UStatus isExpired(UAttributes uAttributes) { + public ValidationResult isExpired(UAttributes uAttributes) { final Optional maybeTtl = uAttributes.ttl(); final Optional maybeTime = UUIDUtils.getTime(uAttributes.id()); if (maybeTime.isEmpty()) { - return UStatus.failed("Invalid Time", Code.INVALID_ARGUMENT); + return ValidationResult.failure("Invalid Time"); } if (maybeTtl.isEmpty()) { - return UStatus.ok("Not Expired"); + return ValidationResult.success(); } int ttl = maybeTtl.get(); if (ttl <= 0) { - return UStatus.ok("Not Expired"); + return ValidationResult.success(); } long delta = System.currentTimeMillis() - maybeTime.get(); - return delta >= ttl ? UStatus.failed("Payload is expired", Code.DEADLINE_EXCEEDED) : UStatus.ok("Not Expired"); + return delta >= ttl ? ValidationResult.failure("Payload is expired") : ValidationResult.success(); } /** * Validate the id attribute, it is required. * @param attributes UAttributes object containing the id to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public UStatus validateId(UAttributes attributes) { + public ValidationResult validateId(UAttributes attributes) { final UUID id = attributes.id(); - return UUIDUtils.isUuid(id) ? UStatus.ok() : - UStatus.failed(String.format("Invalid UUID [%s]", id), Code.INVALID_ARGUMENT.value()); + return UUIDUtils.isUuid(id) ? ValidationResult.success() : + ValidationResult.failure(String.format("Invalid UUID [%s]", id)); } /** * Validate the {@link UPriority} since it is required. * @param attributes UAttributes object containing the message priority to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public UStatus validatePriority(UAttributes attributes) { + public ValidationResult validatePriority(UAttributes attributes) { return attributes.priority() == null ? - UStatus.failed("Priority is missing", Code.INVALID_ARGUMENT.value()) : UStatus.ok(); + ValidationResult.failure("Priority is missing") : ValidationResult.success(); } /** - * Validate the time to live configuration. If the UAttributes does not contain a time to live then the UStatus is ok. + * Validate the time to live configuration. If the UAttributes does not contain a time to live then the ValidationResult is ok. * @param attributes UAttributes object containing the message time to live configuration to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public UStatus validateTtl(UAttributes attributes) { + public ValidationResult validateTtl(UAttributes attributes) { return attributes.ttl() .filter(ttl -> ttl <= 0) - .map(ttl -> UStatus.failed(String.format("Invalid TTL [%s]", ttl), Code.INVALID_ARGUMENT.value())) - .orElse(UStatus.ok()); + .map(ttl -> ValidationResult.failure(String.format("Invalid TTL [%s]", ttl))) + .orElse(ValidationResult.success()); } /** - * Validate the sink UriPart for the default case. If the UAttributes does not contain a sink then the UStatus is ok. + * Validate the sink UriPart for the default case. If the UAttributes does not contain a sink then the ValidationResult is ok. * @param attributes UAttributes object containing the sink to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public UStatus validateSink(UAttributes attributes) { + public ValidationResult validateSink(UAttributes attributes) { return attributes.sink() .map(UriValidator::validate) - .orElse(UStatus.ok()); + .orElse(ValidationResult.success()); } /** - * Validate the permissionLevel for the default case. If the UAttributes does not contain a permission level then the UStatus is ok. + * Validate the permissionLevel for the default case. If the UAttributes does not contain a permission level then the ValidationResult is ok. * @param attributes UAttributes object containing the permission level to validate. - * @return Returns a UStatus indicating if the permissionLevel is valid or not. + * @return Returns a ValidationResult indicating if the permissionLevel is valid or not. */ - public UStatus validatePermissionLevel(UAttributes attributes) { + public ValidationResult validatePermissionLevel(UAttributes attributes) { return attributes.plevel() - .map(permissionLevel -> permissionLevel > 0 ? UStatus.ok() : UStatus.failed("Invalid Permission Level", Code.INVALID_ARGUMENT.value())) - .orElse(UStatus.ok()); + .map(permissionLevel -> permissionLevel > 0 ? ValidationResult.success() : ValidationResult.failure("Invalid Permission Level")) + .orElse(ValidationResult.success()); } /** - * Validate the commStatus for the default case. If the UAttributes does not contain a comm status then the UStatus is ok. + * Validate the commStatus for the default case. If the UAttributes does not contain a comm status then the ValidationResult is ok. * @param attributes UAttributes object containing the comm status to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public UStatus validateCommStatus(UAttributes attributes) { + public ValidationResult validateCommStatus(UAttributes attributes) { return attributes.commstatus().or(() -> Optional.of(Code.OK.value())) .flatMap(Code::from) - .map(code -> UStatus.ok()) - .orElse(UStatus.failed("Invalid Communication Status Code", Code.INVALID_ARGUMENT.value())); + .map(code -> ValidationResult.success()) + .orElse(ValidationResult.failure("Invalid Communication Status Code")); } /** - * Validate the correlationId for the default case. If the UAttributes does not contain a request id then the UStatus is ok. + * Validate the correlationId for the default case. If the UAttributes does not contain a request id then the ValidationResult is ok. * @param attributes Attributes object containing the request id to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public UStatus validateReqId(UAttributes attributes) { + public ValidationResult validateReqId(UAttributes attributes) { return attributes.reqid() .filter(correlationId -> !UUIDUtils.isUuid(correlationId)) - .map(correlationId -> UStatus.failed("Invalid UUID", Code.INVALID_ARGUMENT.value())) - .orElse(UStatus.ok()); + .map(correlationId -> ValidationResult.failure("Invalid UUID")) + .orElse(ValidationResult.success()); } /** * Validate the {@link UMessageType} attribute, it is required. * @param attributes UAttributes object containing the message type to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ - public abstract UStatus validateType(UAttributes attributes); + public abstract ValidationResult validateType(UAttributes attributes); /** * Implements validations for UAttributes that define a message that is meant for publishing state changes. @@ -224,12 +226,12 @@ private static class Publish extends UAttributesValidator { /** * Validates that attributes for a message meant to publish state changes has the correct type. * @param attributes UAttributes object containing the message type to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateType(UAttributes attributes) { - return UMessageType.PUBLISH == attributes.type() ? UStatus.ok() : - UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); + public ValidationResult validateType(UAttributes attributes) { + return UMessageType.PUBLISH == attributes.type() ? ValidationResult.success() : + ValidationResult.failure(String.format("Wrong Attribute Type [%s]", attributes.type())); } @Override @@ -246,38 +248,38 @@ private static class Request extends UAttributesValidator { /** * Validates that attributes for a message meant for an RPC request has the correct type. * @param attributes UAttributes object containing the message type to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateType(UAttributes attributes) { - return UMessageType.REQUEST == attributes.type() ? UStatus.ok() : - UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); + public ValidationResult validateType(UAttributes attributes) { + return UMessageType.REQUEST == attributes.type() ? ValidationResult.success() : + ValidationResult.failure(String.format("Wrong Attribute Type [%s]", attributes.type())); } /** * Validates that attributes for a message meant for an RPC request has a destination sink. * In the case of an RPC request, the sink is required. * @param attributes UAttributes object containing the sink to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateSink(UAttributes attributes) { + public ValidationResult validateSink(UAttributes attributes) { return attributes.sink() .map(UriValidator::validateRpcResponse) - .orElse(UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value())); + .orElse(ValidationResult.failure("Missing Sink")); } /** * Validate the time to live configuration. * In the case of an RPC request, the time to live is required. * @param attributes UAttributes object containing the time to live to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateTtl(UAttributes attributes) { + public ValidationResult validateTtl(UAttributes attributes) { return attributes.ttl() - .map(ttl -> ttl > 0 ? UStatus.ok() : UStatus.failed(String.format("Invalid TTL [%s]", ttl), Code.INVALID_ARGUMENT.value())) - .orElse(UStatus.failed("Missing TTL", Code.INVALID_ARGUMENT.value())); + .map(ttl -> ttl > 0 ? ValidationResult.success() : ValidationResult.failure(String.format("Invalid TTL [%s]", ttl))) + .orElse(ValidationResult.failure("Missing TTL")); } @Override @@ -294,39 +296,39 @@ private static class Response extends UAttributesValidator { /** * Validates that attributes for a message meant for an RPC response has the correct type. * @param attributes UAttributes object containing the message type to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateType(UAttributes attributes) { - return UMessageType.RESPONSE == attributes.type() ? UStatus.ok() : - UStatus.failed(String.format("Wrong Attribute Type [%s]", attributes.type()), Code.INVALID_ARGUMENT.value()); + public ValidationResult validateType(UAttributes attributes) { + return UMessageType.RESPONSE == attributes.type() ? ValidationResult.success() : + ValidationResult.failure(String.format("Wrong Attribute Type [%s]", attributes.type())); } /** * Validates that attributes for a message meant for an RPC response has a destination sink. * In the case of an RPC response, the sink is required. * @param attributes UAttributes object containing the sink to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateSink(UAttributes attributes) { + public ValidationResult validateSink(UAttributes attributes) { return attributes.sink() .map(UriValidator::validateRpcMethod) - .orElse(UStatus.failed("Missing Sink", Code.INVALID_ARGUMENT.value())); + .orElse(ValidationResult.failure("Missing Sink")); } /** * Validate the correlationId. n the case of an RPC response, the correlation id is required. * @param attributes UAttributes object containing the correlation id to validate. - * @return Returns a {@link UStatus} that is success or failed with a failure message. + * @return Returns a {@link ValidationResult} that is success or failed with a failure message. */ @Override - public UStatus validateReqId(UAttributes attributes) { + public ValidationResult validateReqId(UAttributes attributes) { return attributes.reqid() .map(correlationId -> UUIDUtils.isUuid(correlationId) ? - UStatus.ok() : UStatus.failed(String.format("Invalid correlationId [%s]", correlationId), Code.INVALID_ARGUMENT.value())) - .orElse(UStatus.failed("Missing correlationId", Code.INVALID_ARGUMENT.value())); + ValidationResult.success() : ValidationResult.failure(String.format("Invalid correlationId [%s]", correlationId))) + .orElse(ValidationResult.failure("Missing correlationId")); } @Override diff --git a/src/main/java/org/eclipse/uprotocol/uri/builder/UResourceBuilder.java b/src/main/java/org/eclipse/uprotocol/uri/builder/UResourceBuilder.java new file mode 100644 index 00000000..22395d79 --- /dev/null +++ b/src/main/java/org/eclipse/uprotocol/uri/builder/UResourceBuilder.java @@ -0,0 +1,32 @@ +package org.eclipse.uprotocol.uri.builder; + +import org.eclipse.uprotocol.v1.UResource; + +public interface UResourceBuilder { + + /** + * Builds a UResource for an RPC response. + * @return Returns a UResource for an RPC response. + */ + static UResource forRpcResponse() { + return UResource.newBuilder() + .setName("rpc") + .setInstance("response") + .setId(0) + .build(); + } + + + /** + * Builds a UResource for an RPC request. + * @param method The method to be invoked. + * @return Returns a UResource for an RPC request. + */ + static UResource forRpcRequest(String method) { + return UResource.newBuilder() + .setName("rpc") + .setInstance(method) + .build(); + } + +} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java deleted file mode 100644 index 8081b4a6..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UAuthority.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import java.net.InetAddress; -import java.util.Objects; -import java.util.Optional; - -/** - * An Authority represents the deployment location of a specific Software Entity. - * Data representation of an Authority.
An Authority consists of a device, a domain and a micro version in the form of an IP Address.
- * Device and domain names are used as part of the URI for device and service discovery. Optimized micro versions of the UUri will use the IP Address.
- * Devices will be grouped together into realms of Zone of Authority.
- */ -public class UAuthority implements UriFormat { - private final static UAuthority EMPTY = new UAuthority(null, null, null, false, true); - - /** - * A device is a logical independent representation of a service bus in different execution environments.
- * Devices will be grouped together into realms of Zone of Authority. - */ - private final String device; - - /** - * The domain a software entity is deployed on, such as vehicle or backoffice.
- * Vehicle Domain name MUST be that of the vehicle VIN.
- * A domain name is an identification string that defines a realm of administrative autonomy, authority or control within the Internet. - */ - private final String domain; - - /** - * An UAuthority starting with // is a remote configuration of a URI, and we mark the uAuthority implicitly as remote. - * This is never exposed externally and is used internally to indicate remote or local deployments. - */ - private final boolean markedRemote; - - /** - * The device IP address. Represents the micro version of a UAuthority. - */ - private final InetAddress address; - - /** - * Indicates that this UAuthority has already been resolved. - * A resolved UAuthority means that it has all the information needed to be serialised in the long format or the micro format of a UUri. - */ - private final boolean markedResolved; - - /** - * Constructor for building a UAuthority. - * @param device The device a software entity is deployed on, such as the VCU, CCU or cloud provider. - * @param domain The domain a software entity is deployed on, such as vehicle or Cloud (PaaS). - * @param address The device IP address of the device. - * @param markedRemote Indicates if this UAuthority was implicitly marked as remote. - * @param markedResolved Indicates that this uAuthority has all the information needed to be serialised - * in the long format or the micro format of a UUri. - */ - private UAuthority(String device, String domain, InetAddress address, boolean markedRemote, boolean markedResolved) { - this.device = device == null ? null : device.toLowerCase(); - this.domain = domain == null ? null : domain.toLowerCase(); - this.address = address; - this.markedRemote = markedRemote; - this.markedResolved = markedResolved; - } - - /** - * Static factory method for creating a local uAuthority.
- * A local uri does not contain an authority and looks like this: - *
 :<service>/<version>/<resource>#<Message> 
- * @return Returns a local uAuthority that has no domain, device, or ip address information, indicating to uProtocol - * that the uAuthority part in the UUri is relative to the sender/receiver deployment environment. - */ - public static UAuthority local() { - return EMPTY; - } - - /** - * Static factory method for creating a remote authority supporting the long serialization information representation of a UUri.
- * Building a UAuthority with this method will create an unresolved uAuthority that can only be serialised in long UUri format. - * An uri with a long representation of uAUthority can be serialised as follows: - *
 //<device>.<domain>/<service>/<version>/<resource>#<Message> 
- * @param device The device a software entity is deployed on, such as the VCU, CCU or cloud provider. - * @param domain The domain a software entity is deployed on, such as vehicle or Cloud (PaaS). Vehicle Domain name MUST be that of the vehicle VIN. - * @return Returns a uAuthority that contains the device and the domain and can only be serialized in long UUri format. - */ - public static UAuthority longRemote(String device, String domain) { - return new UAuthority(device, domain, null, true, false); - } - - /** - * Static factory method for creating a remote authority supporting the micro serialization information representation of a UUri.
- * Building a UAuthority with this method will create an unresolved uAuthority that can only be serialised in micro UUri format. - * @param address The ip address of the device a software entity is deployed on. - * @return Returns a uAuthority that contains only the internet address of the device, and can only be serialized in micro UUri format. - */ - public static UAuthority microRemote(InetAddress address) { - return new UAuthority(null, null, address, true, false); - } - - /** - * Static factory method for creating a remote authority that is completely resolved with name, device and ip address of the device.
- * Building a UAuthority with this method will enable serialisation in both UUri formats, long UUri format and micro UUri format. - * Note that in the case of missing data, this will not fail, but simply create a UAuthority that is not resolved. - * @param device The device name for long serialization of UUri. - * @param domain The domain name for long serialization of UUri. - * @param address the IP address for the device, for micro serialization of UUri. - * @return Returns a uAuthority that contains all resolved data and so can be serialized into a long UUri or a micro UUri. - */ - public static UAuthority resolvedRemote(String device, String domain, InetAddress address) { - boolean resolved = device != null && !device.isBlank() && address != null; - return new UAuthority(device, domain, address, true, resolved); - } - - /** - * Static factory method for creating an empty uAuthority, to avoid working with null
- * Empty uAuthority is still serializable in both long and micro UUri formats, and will be as local to the current deployment environment. - * @return Returns an empty authority that has no domain, device, or device ip address information. - */ - public static UAuthority empty() { - return EMPTY; - } - - /** - * Accessing an optional device of the uAuthority. - * @return Returns the device a software entity is deployed on, such as the VCU, CCU or cloud provider. - */ - public Optional device() { - return device == null || device.isBlank() ? Optional.empty() : Optional.of(device); - } - - /** - * Accessing an optional domain of the uAuthority. - * @return Returns the domain a software entity is deployed on, such as vehicle or backoffice. - */ - public Optional domain() { - return domain == null || domain.isBlank() ? Optional.empty() : Optional.of(domain); - } - - /** - * Accessing an optional IP address configuration of the uAuthority. - * @return Returns the device IP address. - */ - public Optional address() { - return Optional.ofNullable(address); - } - - /** - * Support for determining if this uAuthority is defined for a local deployment. - * @return returns true if this uAuthority is local, meaning does not contain a device/domain for long UUri or information for micro UUri. - */ - public boolean isLocal() { - return isEmpty() && !isMarkedRemote(); - } - - /** - * Support for determining if this uAuthority defines a deployment that is defined as remote. - * @return Returns true if this uAuthority is remote, meaning it contains information for serialising a long UUri or a micro UUri. - */ - public boolean isRemote() { - return isMarkedRemote(); - } - - /** - * Support for determining if this uAuthority was configured to be remote. - * @return Returns true if this uAuthority is explicitly configured remote deployment. - */ - public boolean isMarkedRemote() { - return markedRemote; - } - - /** - * Indicates that this UAuthority has already been resolved. - * A resolved UAuthority means that it has all the information needed to be serialised in the long format or the micro format of a UUri. - * @return Returns true if this UAuthority is resolved with all the information needed to be serialised in the long format or the micro format of a UUri. - */ - @Override - public boolean isResolved() { - return markedResolved; - } - - /** - * Determine if the UAuthority can be used to serialize a UUri in long format. - * @return Returns true if the UAuthority can be used to serialize a UUri in long format. - */ - @Override - public boolean isLongForm() { - return isLocal() || device().isPresent(); - } - - /** - * Determine if the UAuthority can be used to serialize a UUri in micro format. - * @return Returns true if the uAuthority can be serialized a UUri in micro format. - */ - @Override - public boolean isMicroForm() { - return isLocal() || address().isPresent(); - } - - @Override - public boolean isEmpty() { - return domain().isEmpty() && device().isEmpty() && address().isEmpty(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - UAuthority that = (UAuthority) o; - return markedRemote == that.markedRemote && markedResolved == that.markedResolved && Objects.equals(device, that.device) - && Objects.equals(domain, that.domain) && Objects.equals(address, that.address); - } - - @Override - public int hashCode() { - return Objects.hash(device, domain, markedRemote, address, markedResolved); - } - - @Override - public String toString() { - return "UAuthority{" + - "device='" + device + '\'' + - ", domain='" + domain + '\'' + - ", markedRemote=" + markedRemote + - ", address=" + address + - ", markedResolved=" + markedResolved + - '}'; - } -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java deleted file mode 100644 index 40312605..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UEntity.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import java.util.Objects; -import java.util.Optional; - -/** - * Data representation of an Software Entity - uE
- * Software entities are distinguished by using a unique name or a unique id along with the specific version of the software. - * An Software Entity is a piece of software deployed somewhere on a uDevice.
- * The Software Entity is used in the source and sink parts of communicating software.
- * A uE that publishes events is a Service role.
- * A uE that consumes events is an Application role. - */ -public class UEntity implements UriFormat { - private static final UEntity EMPTY = new UEntity("", null, null, false); - - private final String name; // uE Name - private final Integer version; // uE Major Version - private final Short id; // uE ID - private final boolean markedResolved; // Indicates that this UAuthority has already been resolved. - - /** - * Build a Software Entity that represents a communicating piece of software. - * @param name The name of the software such as petapp or body.access. - * @param version The software version. If not supplied, the latest version of the service will be used. - * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. - * @param markedResolved Indicates that this uResource was populated with intent of having all data. - */ - private UEntity(String name, Integer version, Short id, boolean markedResolved) { - Objects.requireNonNull(name, " Software Entity must have a name"); - this.name = name; - this.id = id; - this.version = version; - this.markedResolved = markedResolved; - } - - /** - * Create a complete UEntity with all the information so that it can be used in long form UUri serialisation and micro form UUri serialisation. - * In the case of missing elements such as name or id, the UEntity will not be marked as resolvable and will not be usable in serialisation formats. - * @param name The name of the software such as petapp or body.access. - * @param version The software version. If not supplied, the latest version of the service will be used. - * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. - * @return Returns a complete UEntity with all the information so that it can be used in long form UUri serialisation and micro form UUri serialisation. - */ - public static UEntity resolvedFormat(String name, Integer version, Short id) { - boolean resolved = name != null && !name.isBlank() && id != null; - return new UEntity(Objects.requireNonNullElse(name, "").trim(), version, id, resolved); - } - - /** - * Static factory method for creating a uE using the software entity name, that can be used in long form UUri serialisation. - * @param name The software entity name, such as petapp or body.access. - * @return Returns an UEntity with the name where the version is the latest version of the service and can only be serialized - * to long UUri format. - */ - public static UEntity longFormat(String name) { - return new UEntity(name, null, null, false); - } - - /** - * Static factory method for creating a uE using the software entity name, that can be used long form UUri serialisation. - * @param name The software entity name, such as petapp or body.access. - * @param version The software entity version. - * @return Returns an UEntity with the name and the version of the service and can only be serialized - * to long UUri format. - */ - public static UEntity longFormat(String name, Integer version) { - return new UEntity(name, version, null, false); - } - - /** - * Static factory method for creating a uE using the software entity identification number, that can be used to serialize micro UUris. - * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. - * @return Returns an UEntity with the name where the version is the latest version of the service and can only be serialized - * to long micro UUri format. - */ - public static UEntity microFormat(Short id) { - return new UEntity("", null, id, false); - } - - /** - * Static factory method for creating a uE using the software entity identification number, that can be used to serialize micro UUris. - * @param id A numeric identifier for the software entity which is a one-to-one correspondence with the software name. - * @param version The software entity version. - * @return Returns an UEntity with the name and the version of the service and can only be serialized - * to micro UUri format. - */ - public static UEntity microFormat(Short id, Integer version) { - return new UEntity("", version, id, false); - } - - /** - * Static factory method for creating an empty software entity, to avoid working with null
- * @return Returns an empty software entity that has a blank name, no unique id and no version information. - */ - public static UEntity empty() { - return EMPTY; - } - - /** - * Indicates that this software entity is an empty container and has no valuable information in building uProtocol sinks or sources. - * @return Returns true if this software entity is an empty container and has no valuable information in building uProtocol sinks or sources. - */ - @Override - public boolean isEmpty() { - return name.isBlank() && version().isEmpty() && id().isEmpty(); - } - - /** - * Return true if the UEntity contains both the name and IDs meaning it contains all the information to be serialized - * into a long UUri or a micro form UUri. - * @return Returns true of this resource contains resolved information meaning it contains all the information to be serialized - * into a long UUri or a micro form UUri. - */ - public boolean isResolved() { - return markedResolved; - } - - /** - * Determine if this software entity can be serialised into a long UUri form. - * @return Returns true if this software entity can be serialised into a long UUri form, meaning it has at least a name. - */ - @Override - public boolean isLongForm() { - return !name().isBlank(); - } - - /** - * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. - * @return Returns true if the Uri part can be serialized into micro form, meaning is has at least a unique numeric identifier. - */ - @Override - public boolean isMicroForm() { - return id().isPresent(); - } - - /** - * @return Returns the name of the software such as petpp or body.access. - */ - public String name() { - return name; - } - - /** - * @return Returns the software version if it exists. - * If the version does not exist, the latest version of the service will be used. - */ - public Optional version() { - return Optional.ofNullable(version); - } - - /** - * @return Returns the software id if it exists. The software id represents the numeric identifier of the uE. - */ - public Optional id() { - return Optional.ofNullable(id); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - UEntity uEntity = (UEntity) o; - return markedResolved == uEntity.markedResolved && Objects.equals(name, uEntity.name) - && Objects.equals(version, uEntity.version) && Objects.equals(id, uEntity.id); - } - - @Override - public int hashCode() { - return Objects.hash(name, version, id, markedResolved); - } - - - @Override - public String toString() { - return "UEntity{" + - "name='" + name + '\'' + - ", version=" + version + - ", id=" + id + - ", markedResolved=" + markedResolved + - '}'; - } -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java deleted file mode 100644 index 4652c990..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UResource.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import java.util.Objects; -import java.util.Optional; - -/** - * A service API - defined in the {@link UEntity} - has Resources and Methods. Both of these are represented by the UResource class.
- * A uResource represents a resource from a Service such as "door" and an optional specific instance such as "front_left". In addition, it can optionally contain - * the name of the resource Message type, such as "Door". The Message type matches the protobuf service IDL that defines structured data types.
- * An UResource is something that can be manipulated/controlled/exposed by a service. Resources are unique when prepended with UAuthority that represents the device and - * UEntity that represents the service. - */ -public class UResource implements UriFormat { - - private static final UResource EMPTY = new UResource("", null,null, null, false); - - private static final UResource RESPONSE = new UResource("rpc", "response",null, (short) 0, true); - - private final String name; - - private final String instance; - - private final String message; - - private final Short id; - - private final boolean markedResolved; // Indicates that this UAuthority has already been resolved. - - /** - * Create a uResource. The resource is something that is manipulated by a service such as a door. - * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @param instance An instance of a resource such as front_left. - * @param message The Message type matches the protobuf service IDL message name that defines structured data types. - * A message is a data structure type used to define data that is passed in events and rpc methods. - * @param id The numeric representation of this uResource. - * @param markedResolved Indicates that this uResource was populated with intent of having all data. - */ - private UResource(String name, String instance, String message, Short id, boolean markedResolved) { - this.name = Objects.requireNonNullElse(name, ""); - this.instance = instance; - this.message = message; - this.id = id; - this.markedResolved = markedResolved; - } - - /** - * Build a UResource that has all elements resolved and can be serialized in a long UUri or a micro UUri. - * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @param instance An instance of a resource such as front_left. - * @param message The Message type matches the protobuf service IDL message name that defines structured data types. - * A message is a data structure type used to define data that is passed in events and rpc methods. - * @param id The numeric representation of this uResource. - * @return Returns a UResource that has all the information that is needed to serialize into a long UUri or a micro UUri. - */ - public static UResource resolvedFormat(String name, String instance, String message, Short id) { - boolean resolved = name != null && !name.isBlank() && id != null; - return new UResource(name, instance, message, id, resolved); - } - - /** - * Build a UResource that can be serialized into a long UUri. Mostly used for publishing messages. - * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @return Returns a UResource that can be serialized into a long UUri. - */ - public static UResource longFormat(String name) { - return new UResource(name, null, null, null, false); - } - - /** - * Build a UResource that can be serialized into a long UUri. Mostly used for publishing messages. - * @param name The name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - * @param instance An instance of a resource such as front_left. - * @param message The Message type matches the protobuf service IDL message name that defines structured data types. - * A message is a data structure type used to define data that is passed in events and rpc methods. - * @return Returns a UResource that can be serialised into a long UUri. - */ - public static UResource longFormat(String name, String instance, String message) { - return new UResource(name, instance, message, null, false); - } - - /** - * Build a UResource that can be serialised into a micro UUri. Mostly used for publishing messages. - * @param id The numeric representation of this uResource. - * @return Returns a UResource that can be serialised into a micro UUri. - */ - public static UResource microFormat(Short id) { - return new UResource("", null, null, id, false); - } - - /** - * Build a UResource for rpc request, using only the long format. - * @param methodName The RPC method name. - * @return Returns a UResource used for an RPC request that could be serialised in long format. - */ - public static UResource forRpcRequest(String methodName) { - return new UResource("rpc", methodName, null, null, false); - } - - /** - * Build a UResource for rpc request, using only the micro format. - * @param methodId The numeric representation method name for the RPC. - * @return Returns a UResource used for an RPC request that could be serialised in micro format. - */ - public static UResource forRpcRequest(Short methodId) { - return new UResource("rpc", null, null, methodId, false); - } - - /** - * Build a UResource for rpc request, using both the long and micro format information. - * @param methodName The RPC method name. - * @param methodId The numeric representation method name for the RPC. - * @return Returns a UResource used for an RPC request that could be serialised in long and micro format. - */ - public static UResource forRpcRequest(String methodName, Short methodId) { - boolean resolved = methodName != null && !methodName.isBlank() && methodId != null; - return new UResource("rpc", methodName, null, methodId, resolved); - } - - /** - * Static factory method for creating a response resource that is returned from RPC calls
- * @return Returns a response resource used for response RPC calls. - */ - public static UResource forRpcResponse() { - return RESPONSE; - } - - /** - * @return Returns true if this resource specifies an RPC method call or RPC response. - */ - public boolean isRPCMethod() { - return (name.equals("rpc") && instance().isPresent()) || - (name.equals("rpc") && id().isPresent()); - } - - /** - * Static factory method for creating an empty resource, to avoid working with null
- * @return Returns an empty resource that has a blank name and no message instance information. - */ - public static UResource empty() { - return EMPTY; - } - - /** - * Indicates that this resource is an empty container and has no valuable information in building uProtocol URI. - * @return Returns true if this resource is an empty container and has no valuable information in building uProtocol URI. - */ - public boolean isEmpty() { - return (name.isBlank() || "rpc".equals(name)) && instance().isEmpty() && message().isEmpty() && id().isEmpty(); - } - - /** - * @return Returns the name of the resource as a noun such as door or window, or in the case a method that manipulates the resource, a verb. - */ - public String name() { - return name; - } - - /** - * @return Returns the resource id if it exists. - */ - public Optional id() { - return Optional.ofNullable(id); - } - - /** - * An instance of a resource such as front_left - * or in the case of RPC a method name that manipulates the resource such as UpdateDoor. - * @return Returns the resource instance of the resource if it exists. - * If the instance does not exist, it is assumed that all the instances of the resource are wanted. - */ - public Optional instance() { - return instance == null || instance.isBlank() ? Optional.empty() : Optional.of(instance); - } - - /** - * The Message type matches the protobuf service IDL that defines structured data types. - * A message is a data structure type used to define data that is passed in events and rpc methods. - * @return Returns the Message type matches the protobuf service IDL that defines structured data types. - */ - public Optional message() { - return message == null || message.isBlank() ? Optional.empty() : Optional.of(message); - } - - /** - * Return true if this resource contains both ID and names. - * Method type of UResource requires name, instance, and ID where a topic - * type of UResource also requires message to not be null - * @return Returns true of this resource contains resolved information - */ - public boolean isResolved() { - return markedResolved; - } - - /** - * Returns true if the uResource contains names so that it can be serialized to long format. - * @return Returns true if the uResource contains names so that it can be serialized to long format. - */ - @Override - public boolean isLongForm() { - if (name.equals("rpc")) { - return instance().isPresent(); - } - return !name().isBlank(); - } - - /** - * Returns true if the uResource contains the id's which will allow the Uri part to be serialized into micro form. - * @return Returns true if the uResource can be serialized into micro form. - */ - @Override - public boolean isMicroForm() { - return id().isPresent(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - UResource uResource = (UResource) o; - return markedResolved == uResource.markedResolved && Objects.equals(name, uResource.name) - && Objects.equals(instance, uResource.instance) && Objects.equals(message, uResource.message) - && Objects.equals(id, uResource.id); - } - - @Override - public int hashCode() { - return Objects.hash(name, instance, message, id, markedResolved); - } - - @Override - public String toString() { - return "UResource{" + - "name='" + name + '\'' + - ", instance='" + instance + '\'' + - ", message='" + message + '\'' + - ", id=" + id + - ", markedResolved=" + markedResolved + - '}'; - } -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java deleted file mode 100644 index b629b4ad..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UUri.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import java.util.Objects; - -/** - * Data representation of uProtocol URI. - * This class will be used to represent the source and sink (destination) parts of the Packet, for example in a CloudEvent Packet.
- * UUri is used as a method to uniquely identify devices, services, and resources on the network.
- * Where software is deployed, what the service is called along with a version and the resources in the service. - * Defining a common URI for the system allows applications and/or services to publish and discover each other - * as well as maintain a database/repository of microservices in the various vehicles.
- * Example for long format serialization: - *
- *     //<device>.<domain>/<service>/<version>/<resource>#<message>
- * 
- * - */ -public class UUri implements UriFormat { - private static final UUri EMPTY = new UUri(UAuthority.empty(), UEntity.empty(), UResource.empty()); - - private final UAuthority uAuthority; - private final UEntity uEntity; - private final UResource uResource; - - /** - * Create a full URI. - * @param uAuthority The uAuthority represents the deployment location of a specific Software Entity . - * @param uEntity The uEntity in the role of a service or in the role of an application is the software and version. - * @param uResource The uResource is something that is manipulated by a service such as a Door. - */ - public UUri(UAuthority uAuthority, UEntity uEntity, UResource uResource) { - this.uAuthority = Objects.requireNonNullElse(uAuthority, UAuthority.empty()); - this.uEntity = Objects.requireNonNullElse(uEntity, UEntity.empty()); - this.uResource = Objects.requireNonNullElse(uResource, UResource.empty()); - } - - /** - * Create a URI for a resource. This will match all the specific instances of the resource, - * for example all the instances of the vehicle doors. - * @param uAuthority The Authority represents the deployment location of a specific Software Entity. - * @param uEntity The USE in the role of a service or in the role of an application. - * @param uResource The resource is something that is manipulated by a service such as a Door. - */ - public UUri(UAuthority uAuthority, UEntity uEntity, String uResource) { - this(uAuthority, uEntity, UResource.longFormat(uResource)); - } - - /** - * Create an RPC Response UUri passing the Authority and Entity information. - * @param uAuthority The uAuthority represents the deployment location of a specific Software Entity. - * @param uEntity The SW entity information. - * @return Returns a UUri of a constructed RPC Response. - */ - public static UUri rpcResponse(UAuthority uAuthority, UEntity uEntity) { - return new UUri(uAuthority, uEntity, UResource.forRpcResponse()); - } - - - /** - * Static factory method for creating an empty uri, to avoid working with null
- * @return Returns an empty uri to avoid working with null. - */ - public static UUri empty() { - return EMPTY; - } - - /** - * Indicates that this URI is an empty container and has no valuable information in building uProtocol sinks or sources. - * @return Returns true if this URI is an empty container and has no valuable information in building uProtocol sinks or sources. - */ - @Override - public boolean isEmpty() { - return uAuthority.isEmpty() && uEntity().isEmpty() && uResource.isEmpty(); - } - - /** - * Returns true if URI contains both names and numeric representations of the names inside its belly. - * Meaning that this UUri can be serialized to long or micro formats. - * @return Returns true if URI contains both names and numeric representations of the names inside its belly. - * Meaning that this UUri can buree serialized to long or micro formats. - */ - @Override - public boolean isResolved() { - return uAuthority.isResolved() && uEntity.isResolved() && uResource.isResolved(); - } - - /** - * Determines if this UUri can be serialized into a long form UUri. - * @return Returns true if this UUri can be serialized into a long form UUri. - */ - @Override - public boolean isLongForm() { - return uAuthority.isLongForm() && - (uEntity.isLongForm() || uEntity.isEmpty()) && - (uResource.isLongForm() || uResource().isEmpty()); - } - - /** - * Determines if this UUri can be serialized into a micro form UUri. - * @return Returns true if this UUri can be serialized into a micro form UUri. - */ - @Override - public boolean isMicroForm() { - return uAuthority.isMicroForm() && uEntity.isMicroForm() && uResource.isMicroForm(); - } - - /** - * @return Returns the Authority represents the deployment location of a specific Software Entity. - */ - public UAuthority uAuthority() { - return uAuthority; - } - - /** - * @return Returns the USE in the role of a service or in the role of an application. - */ - public UEntity uEntity() { - return uEntity; - } - - /** - * @return Returns the resource, something that is manipulated by a service such as a Door. - */ - public UResource uResource() { - return this.uResource; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - UUri uri = (UUri) o; - return Objects.equals(uAuthority, uri.uAuthority) && Objects.equals(uEntity, uri.uEntity) - && Objects.equals(uResource, uri.uResource); - } - - @Override - public int hashCode() { - return Objects.hash(uAuthority, uEntity, uResource); - } - - @Override - public String toString() { - return "UriPart{" + - "uAuthority=" + uAuthority + - ", uEntity=" + uEntity + - ", uResource=" + uResource + - '}'; - } -} \ No newline at end of file diff --git a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java b/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java deleted file mode 100644 index 9e337750..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/datamodel/UriFormat.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.eclipse.uprotocol.uri.datamodel; - -/** - * Interface used to provide hints as to how the Uri part or Uri itself is formatted meaning does it contain - * long format, micro format or both (resolved) information. - */ -public interface UriFormat { - - /** - * Supporting empty Uri parts enables avoiding null values in the data model, and can indicate the absence of a Uri Part. - * @return Returns true if the Uri part is empty. - */ - boolean isEmpty(); - - /** - * Returns true if the Uri part contains both names and ids (numbers) corresponding to the data inside its belly. - * isResolved true means that the Uri part can be serialized to both long and micro uri format. - * @return Returns true if the Uri part contains both names and ids (numbers), long and micro representations. - */ - boolean isResolved(); - - /** - * Returns true if the Uri part contains names so that it can be serialized to long format. - * @return Returns true if the Uri part contains names so that it can be serialized to long format. - */ - boolean isLongForm(); - - /** - * Returns true if the Uri part contains the id's which will allow the Uri part to be serialized into micro form. - * @return Returns true if the Uri part can be serialized into micro form. - */ - boolean isMicroForm(); -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java index 01298265..57a98027 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.java @@ -21,15 +21,14 @@ package org.eclipse.uprotocol.uri.serializer; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import java.util.Arrays; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; +import org.eclipse.uprotocol.uri.validator.UriValidator; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; /** * UUri Serializer that serializes a UUri to a long format string per @@ -52,38 +51,40 @@ public static LongUriSerializer instance() { */ @Override public String serialize(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { + if (Uri == null || UriValidator.isEmpty(Uri)) { return ""; } StringBuilder sb = new StringBuilder(); - sb.append(buildAuthorityPartOfUri(Uri.uAuthority())); - - if (Uri.uAuthority().isMarkedRemote()) { - sb.append("/"); - } - - if (Uri.uEntity().isEmpty()) { - return sb.toString(); + if (Uri.hasAuthority()) { + sb.append(buildAuthorityPartOfUri(Uri.getAuthority())); } + sb.append("/"); - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity())); + sb.append(buildSoftwareEntityPartOfUri(Uri.getEntity())); - sb.append(buildResourcePartOfUri(Uri.uResource())); + sb.append(buildResourcePartOfUri(Uri)); return sb.toString().replaceAll("/+$", ""); } - private static String buildResourcePartOfUri(UResource uResource) { - if (uResource.isEmpty()) { + private static String buildResourcePartOfUri(UUri uri) { + if (!uri.hasResource()) { return ""; } + final UResource uResource = uri.getResource(); + StringBuilder sb = new StringBuilder("/"); - sb.append(uResource.name()); - uResource.instance().ifPresent(instance -> sb.append(".").append(instance)); - uResource.message().ifPresent(message -> sb.append("#").append(message)); + sb.append(uResource.getName()); + if (uResource.hasInstance()) { + sb.append(".").append(uResource.getInstance()); + } + if (uResource.hasMessage()) { + sb.append("#").append(uResource.getMessage()); + } + return sb.toString(); } @@ -92,9 +93,11 @@ private static String buildResourcePartOfUri(UResource uResource) { * @param use Software Entity representing a service or an application. */ private static String buildSoftwareEntityPartOfUri(UEntity use) { - StringBuilder sb = new StringBuilder(use.name().trim()); + StringBuilder sb = new StringBuilder(use.getName().trim()); sb.append("/"); - use.version().ifPresent(sb::append); + if (use.getVersionMajor() > 0) { + sb.append(use.getVersionMajor()); + } return sb.toString(); } @@ -102,22 +105,17 @@ private static String buildSoftwareEntityPartOfUri(UEntity use) { /** * Create the authority part of the uProtocol URI from an authority object. - * @param Authority represents the deployment location of a specific Software Entity in the Ultiverse. + * @param Authority represents the deployment location of a specific Software Entity. * @return Returns the String representation of the Authority in the uProtocol URI. */ private static String buildAuthorityPartOfUri(UAuthority Authority) { - if (Authority.isLocal()) { - return "/"; - } + StringBuilder partialURI = new StringBuilder("//"); - final Optional maybeDevice = Authority.device(); - final Optional maybeDomain = Authority.domain(); + final Optional maybeName = Optional.ofNullable(Authority.getName()); - if (maybeDevice.isPresent()) { - partialURI.append(maybeDevice.get()); - maybeDomain.ifPresent(domain -> partialURI.append(".")); + if (maybeName.isPresent()) { + partialURI.append(maybeName.get()); } - maybeDomain.ifPresent(partialURI::append); return partialURI.toString(); } @@ -130,7 +128,7 @@ private static String buildAuthorityPartOfUri(UAuthority Authority) { @Override public UUri deserialize(String uProtocolUri) { if (uProtocolUri == null || uProtocolUri.isBlank()) { - return UUri.empty(); + return UUri.getDefaultInstance(); } String uri = uProtocolUri.contains(":") ? uProtocolUri.substring(uProtocolUri.indexOf(":")+1) : uProtocolUri @@ -142,52 +140,47 @@ public UUri deserialize(String uProtocolUri) { final int numberOfPartsInUri = uriParts.length; if(numberOfPartsInUri == 0 || numberOfPartsInUri == 1) { - return isLocal ? UUri.empty() : - new UUri(UAuthority.longRemote("", ""), UEntity.empty(), UResource.empty()); + return UUri.getDefaultInstance(); } String useName; String useVersion = ""; - UResource uResource; + UResource uResource = null; + + UAuthority uAuthority = null; - UAuthority uAuthority; if(isLocal) { - uAuthority = UAuthority.local(); useName = uriParts[1]; if (numberOfPartsInUri > 2) { useVersion = uriParts[2]; - uResource = numberOfPartsInUri > 3 ? parseFromString(uriParts[3]) : UResource.empty(); - - } else { - uResource = UResource.empty(); - } + if (numberOfPartsInUri > 3) { + uResource = parseFromString(uriParts[3]); + } + } } else { - String[] authorityParts = uriParts[2].split("\\."); - String device = authorityParts[0]; - String domain = ""; - if (authorityParts.length > 1) { - domain = Arrays.stream(authorityParts) - .skip(1) - .collect(Collectors.joining(".")); + // If authority is blank, it is an error + if (uriParts[2].isBlank()) { + return UUri.getDefaultInstance(); } - uAuthority = UAuthority.longRemote(device, domain); + uAuthority = UAuthority.newBuilder().setName(uriParts[2]).build(); if (uriParts.length > 3) { useName = uriParts[3]; if (numberOfPartsInUri > 4) { useVersion = uriParts[4]; - uResource = numberOfPartsInUri > 5 ? parseFromString(uriParts[5]) : UResource.empty(); + if (numberOfPartsInUri > 5) { + uResource = parseFromString(uriParts[5]); + } - } else { - uResource = UResource.empty(); - } + } } else { - return new UUri(uAuthority, UEntity.empty(), UResource.empty()); + return UUri.newBuilder() + .setAuthority(uAuthority) + .build(); } - } Integer useVersionInt = null; @@ -195,9 +188,24 @@ public UUri deserialize(String uProtocolUri) { if (!useVersion.isBlank()) { useVersionInt = Integer.valueOf(useVersion); } - } catch (NumberFormatException ignored) {} + } catch (NumberFormatException ignored) { + return UUri.getDefaultInstance(); + } + + UEntity.Builder uEntityBuilder = UEntity.newBuilder().setName(useName); - return new UUri(uAuthority, UEntity.longFormat(useName, useVersionInt), uResource); + if (useVersionInt != null) { + uEntityBuilder.setVersionMajor(useVersionInt); + } + + UUri.Builder uriBuilder = UUri.newBuilder().setEntity(uEntityBuilder); + if (uAuthority != null) { + uriBuilder.setAuthority(uAuthority); + } + if (uResource != null) { + uriBuilder.setResource(uResource); + } + return uriBuilder.build(); } /** @@ -215,7 +223,16 @@ private static UResource parseFromString(String resourceString) { String resourceName = nameAndInstanceParts[0]; String resourceInstance = nameAndInstanceParts.length > 1 ? nameAndInstanceParts[1] : null; String resourceMessage = parts.length > 1 ? parts[1] : null; - return UResource.longFormat(resourceName, resourceInstance, resourceMessage); + + UResource.Builder uResourceBuilder = UResource.newBuilder().setName(resourceName); + if (resourceInstance != null) { + uResourceBuilder.setInstance(resourceInstance); + } + if (resourceMessage != null) { + uResourceBuilder.setMessage(resourceMessage); + } + + return uResourceBuilder.build(); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java index 4d49f9fc..3a048001 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.java @@ -21,18 +21,20 @@ package org.eclipse.uprotocol.uri.serializer; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.net.Inet4Address; -import java.net.InetAddress; import java.util.Arrays; import java.util.Optional; +import org.eclipse.uprotocol.uri.validator.UriValidator; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; + +import com.google.protobuf.ByteString; + /** * UUri Serializer that serializes a UUri to a byte[] (micro format) per * ... @@ -61,7 +63,8 @@ public static MicroUriSerializer instance() { private enum AddressType { LOCAL(0), IPv4(1), - IPv6(2); + IPv6(2), + ID(3); private final int value; @@ -87,27 +90,48 @@ public static Optional from(int value) { */ @Override public byte[] serialize(UUri Uri) { - if (Uri == null || Uri.isEmpty() || !Uri.isMicroForm()) { + AddressType type = AddressType.LOCAL; + + if (Uri == null || UriValidator.isEmpty(Uri) || !UriValidator.isMicroForm(Uri)) { return new byte[0]; } - Optional maybeAddress = Uri.uAuthority().address(); - Optional maybeUeId = Uri.uEntity().id(); - Optional maybeUResourceId = Uri.uResource().id(); + Optional maybeUeId = Optional.ofNullable(Uri.getEntity().getId()); + Optional maybeUResourceId = Optional.ofNullable(Uri.getResource().getId()); ByteArrayOutputStream os = new ByteArrayOutputStream(); // UP_VERSION os.write(UP_VERSION); - // TYPE - if (maybeAddress.isPresent()) { - os.write(maybeAddress.get() instanceof Inet4Address ? - AddressType.IPv4.getValue() : AddressType.IPv6.getValue()); - } else { - os.write(AddressType.LOCAL.getValue()); + // Determine the uAuthority type to be written + switch (Uri.getAuthority().getRemoteCase()) { + case REMOTE_NOT_SET: + type = AddressType.LOCAL; + break; + case IP: + final Integer length = Uri.getAuthority().getIp().size(); + if (length == 4) { + type = AddressType.IPv4; + } else if (length == 16) { + type = AddressType.IPv6; + } else { + return new byte[0]; + } + break; + + case ID: + type = AddressType.ID; + break; + + default: + return new byte[0]; } + + + os.write(type.getValue()); + // URESOURCE_ID os.write(maybeUResourceId.get()>>8); os.write(maybeUResourceId.get()); @@ -117,20 +141,35 @@ public byte[] serialize(UUri Uri) { os.write(maybeUeId.get()); // UE_VERSION - Optional version = Uri.uEntity().version(); - os.write(version.map(Integer::byteValue).orElseGet(() -> (byte) 0)); + os.write(Uri.getEntity().getVersionMajor() == 0 ? (byte)0 : Uri.getEntity().getVersionMajor()); // UNUSED os.write((byte)0); // UAUTHORITY_ADDRESS - final Optional maybeUAuthorityAddressBytes = calculateUAuthorityBytes(Uri.uAuthority()); + final Optional maybeUAuthorityAddressBytes; + switch(Uri.getAuthority().getRemoteCase()) { + case IP: + maybeUAuthorityAddressBytes = Optional.ofNullable(Uri.getAuthority().getIp().toByteArray()); + break; + case ID: + maybeUAuthorityAddressBytes = Optional.ofNullable(Uri.getAuthority().getId().toByteArray()); + break; + default: + maybeUAuthorityAddressBytes = Optional.empty(); + } + + // Write the ID length if the type is ID if (maybeUAuthorityAddressBytes.isPresent()) { + if (Uri.getAuthority().getRemoteCase() == UAuthority.RemoteCase.IP) { + os.write(Uri.getAuthority().getId().size()); + } + try { os.write(maybeUAuthorityAddressBytes.get()); } catch (IOException e) { - //NOTE: It is impossible for this exception to be thrown as we can never pass invalid address - return new byte[0]; + // TODO Auto-generated catch block + e.printStackTrace(); } } @@ -138,10 +177,6 @@ public byte[] serialize(UUri Uri) { } - private static Optional calculateUAuthorityBytes(UAuthority uAuthority) { - Optional maybeAddress = uAuthority.address(); - return maybeAddress.map(InetAddress::getAddress); - } /** * Deserialize a byte[] into a {@link UUri} object. @@ -151,12 +186,12 @@ private static Optional calculateUAuthorityBytes(UAuthority uAuthority) @Override public UUri deserialize(byte[] microUri) { if (microUri == null || microUri.length < LOCAL_MICRO_URI_LENGTH ) { - return UUri.empty(); + return UUri.getDefaultInstance(); } // Need to be version 1 if (microUri[0] != 0x1) { - return UUri.empty(); + return UUri.getDefaultInstance(); } int uResourceId = ((microUri[2] & 0xFF) << 8) | (microUri[3] & 0xFF); @@ -165,46 +200,55 @@ public UUri deserialize(byte[] microUri) { // Validate Type is found if (type.isEmpty()) { - return UUri.empty(); + return UUri.getDefaultInstance(); } // Validate that the microUri is the correct length for the type final AddressType addressType = type.get(); if (addressType == AddressType.LOCAL && microUri.length != LOCAL_MICRO_URI_LENGTH) { - return UUri.empty(); + return UUri.getDefaultInstance(); } else if (addressType == AddressType.IPv4 && microUri.length != IPV4_MICRO_URI_LENGTH) { - return UUri.empty(); + return UUri.getDefaultInstance(); } else if (addressType == AddressType.IPv6 && microUri.length != IPV6_MICRO_URI_LENGTH) { - return UUri.empty(); + return UUri.getDefaultInstance(); } // UENTITY_ID int ueId = ((microUri[4] & 0xFF) << 8) | (microUri[5] & 0xFF); // UE_VERSION - int uiVersion = microUri[6]; + int uiVersion = Byte.toUnsignedInt(microUri[6]); // Calculate uAuthority - UAuthority uAuthority; - if (addressType == AddressType.LOCAL) { - uAuthority = UAuthority.local(); - } else { - try { - final InetAddress inetAddress = InetAddress.getByAddress( - Arrays.copyOfRange(microUri, 8, (addressType == AddressType.IPv4) ? - IPV4_MICRO_URI_LENGTH : IPV6_MICRO_URI_LENGTH)); - uAuthority = UAuthority.microRemote(inetAddress); - } catch (Exception e) { - // NOTE: It is impossible for this exception to be thrown as we cannot put invalid data in the fixed size - // microUri - uAuthority = UAuthority.local(); - } + UAuthority uAuthority = null; + switch (addressType) { + case IPv4: + case IPv6: + uAuthority = UAuthority.newBuilder().setIp(ByteString.copyFrom(microUri, 8, + addressType == AddressType.IPv4 ? 4 : 16)).build(); + break; + case ID: + int length = microUri[8]; + uAuthority = UAuthority.newBuilder().setId(ByteString.copyFrom(microUri, 9, + length)).build(); + break; + default: + break; + } + + UUri.Builder uriBuilder = UUri.newBuilder() + .setEntity(UEntity.newBuilder() + .setId(ueId) + .setVersionMajor(uiVersion)) + .setResource(UResource.newBuilder() + .setId(uResourceId)); + if (uAuthority != null) { + uriBuilder.setAuthority(uAuthority); } - return new UUri(uAuthority, - UEntity.microFormat((short)ueId, uiVersion == 0 ? null : uiVersion), - UResource.microFormat((short)uResourceId)); + + return uriBuilder.build(); } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java deleted file mode 100644 index fdff236e..00000000 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.serializer; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; - -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * UUri Serializer that serializes a UUri to a short format per - * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc - */ -public class ShortUriSerializer implements UriSerializer { - - private static final String SCHEME = "s:"; // Required Scheme - - private static final ShortUriSerializer INSTANCE = new ShortUriSerializer(); - - private ShortUriSerializer(){} - - public static ShortUriSerializer instance() { - return INSTANCE; - } - - /** - * Support for serializing {@link UUri} objects into the short URI format. - * @param Uri {@link UUri} object to be serialized to the short URI format. - * @return Returns the short URI formatted string of the supplied {@link UUri} that can be used as a - * sink or a source in a uProtocol publish communication. - */ - @Override - public String serialize(UUri Uri) { - if (Uri == null || Uri.isEmpty()) { - return ""; - } - - StringBuilder sb = new StringBuilder(SCHEME); - - sb.append(buildAuthorityPartOfUri(Uri.uAuthority())); - - if (Uri.uAuthority().isMarkedRemote()) { - sb.append("/"); - } - - if (Uri.uEntity().isEmpty()) { - return sb.toString(); - } - - sb.append(buildSoftwareEntityPartOfUri(Uri.uEntity())); - - sb.append(buildResourcePartOfUri(Uri.uResource())); - - return sb.toString().replaceAll("/+$", ""); - } - - /** - * Deserialize a Short formatted string into a UUri object. - * @param uProtocolUri A short format uProtocol URI. - * @return Returns an UUri data object. - */ - @Override - public UUri deserialize(String uProtocolUri) { - if (uProtocolUri == null || uProtocolUri.isBlank() || !uProtocolUri.contains(SCHEME)) { - return UUri.empty(); - } - - String uri = uProtocolUri.substring(uProtocolUri.indexOf(":")+1).replace('\\', '/'); - - boolean isLocal = !uri.startsWith("//"); - - final String[] uriParts = uri.split("/"); - final int numberOfPartsInUri = uriParts.length; - - if(numberOfPartsInUri == 0 || numberOfPartsInUri == 1) { - return isLocal ? UUri.empty() : - new UUri(UAuthority.longRemote("", ""), UEntity.empty(), UResource.empty()); - } - - String useName = ""; - String useVersion = ""; - UResource uResource; - UAuthority uAuthority; - String[] authorityParts = uriParts[2].split("\\."); - String device = authorityParts[0]; - String domain = ""; - - if (authorityParts.length > 1) { - domain = Arrays.stream(authorityParts) - .skip(1) - .collect(Collectors.joining(".")); - } - uAuthority = UAuthority.longRemote(device, domain); - - if (uriParts.length > 3) { - useName = uriParts[3]; - if (numberOfPartsInUri > 4) { - useVersion = uriParts[4]; - - if (numberOfPartsInUri > 5) { - try { - Short resourceId = Short.valueOf(uriParts[5]); - uResource = UResource.microFormat(resourceId); - } catch (NumberFormatException ignored) { - return UUri.empty(); - } - } else { - uResource = UResource.empty(); - } - } else { - uResource = UResource.empty(); - } - - } else { - return new UUri(uAuthority, UEntity.empty(), UResource.empty()); - } - - Integer useVersionInt = null; - try { - if (!useVersion.isBlank()) { - useVersionInt = Integer.valueOf(useVersion); - } - } catch (NumberFormatException ignored) { - return UUri.empty(); - } - - Short useId = null; - try { - if (!useName.isBlank()) { - useId = Short.valueOf(useName); - } - } catch (NumberFormatException ignored) { - return UUri.empty(); - } - - return new UUri(uAuthority, UEntity.microFormat(useId, useVersionInt), uResource); - } - - - private static String buildResourcePartOfUri(UResource uResource) { - if (uResource.isEmpty() || !uResource.isMicroForm()) { - return ""; - } - StringBuilder sb = new StringBuilder("/"); - uResource.id().ifPresent(id -> sb.append(id)); - - return sb.toString(); - } - - - private static String buildSoftwareEntityPartOfUri(UEntity use) { - StringBuilder sb = new StringBuilder(); - use.id().ifPresent(sb::append); - sb.append("/"); - use.version().ifPresent(sb::append); - return sb.toString(); - } - - - private static String buildAuthorityPartOfUri(UAuthority Authority) { - if (Authority.isLocal()) { - return "/"; - } - StringBuilder partialURI = new StringBuilder("//"); - final Optional maybeDevice = Authority.device(); - final Optional maybeDomain = Authority.domain(); - - if (maybeDevice.isPresent()) { - partialURI.append(maybeDevice.get()); - maybeDomain.ifPresent(domain -> partialURI.append(".")); - } - maybeDomain.ifPresent(partialURI::append); - - return partialURI.toString(); - } -} diff --git a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java index 6c34d4bf..0350de46 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java +++ b/src/main/java/org/eclipse/uprotocol/uri/serializer/UriSerializer.java @@ -21,13 +21,15 @@ package org.eclipse.uprotocol.uri.serializer; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; import java.util.Optional; +import org.eclipse.uprotocol.uri.validator.UriValidator; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; + /** * UUris are used in transport layers and hence need to be serialized. * Each transport supports different serialization formats. @@ -59,30 +61,30 @@ public interface UriSerializer { default Optional buildResolved(String longUri, byte[] microUri) { if ((longUri == null || longUri.isEmpty()) && (microUri == null || microUri.length == 0)) { - return Optional.of(UUri.empty()); + return Optional.of(UUri.getDefaultInstance()); } UUri longUUri = LongUriSerializer.instance().deserialize(longUri); UUri microUUri = MicroUriSerializer.instance().deserialize(microUri); - - UAuthority uAuthority = longUUri.uAuthority().isLocal() ? UAuthority.local() : - UAuthority.resolvedRemote( - longUUri.uAuthority().device().orElse(null), - longUUri.uAuthority().domain().orElse(null), - microUUri.uAuthority().address().orElse(null)); + + final UAuthority.Builder uAuthorityBuilder = + UAuthority.newBuilder(microUUri.getAuthority()) + .setName(longUUri.getAuthority().getName()); + - UEntity uEntity = UEntity.resolvedFormat( - longUUri.uEntity().name(), longUUri.uEntity().version().orElse(null), - microUUri.uEntity().id().orElse(null)); + final UEntity.Builder uEntityBuilder = UEntity.newBuilder(microUUri.getEntity()) + .setName(longUUri.getEntity().getName()); + - UResource uResource = UResource.resolvedFormat( - longUUri.uResource().name(), - longUUri.uResource().instance().orElse(null), - longUUri.uResource().message().orElse(null), - microUUri.uResource().id().orElse(null)); + final UResource.Builder uResourceBuilder = UResource.newBuilder(longUUri.getResource()) + .setId(microUUri.getResource().getId()); - UUri uUri = new UUri(uAuthority, uEntity, uResource); - return uUri.isResolved() ? Optional.of(uUri) : Optional.empty(); - } + UUri uUri = UUri.newBuilder() + .setAuthority(uAuthorityBuilder) + .setEntity(uEntityBuilder) + .setResource(uResourceBuilder) + .build(); + return UriValidator.isResolved(uUri) ? Optional.of(uUri) : Optional.empty(); + } } diff --git a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java index b8f0a96d..16223542 100644 --- a/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uri/validator/UriValidator.java @@ -1,9 +1,11 @@ package org.eclipse.uprotocol.uri.validator; -import org.eclipse.uprotocol.transport.datamodel.UStatus; -import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import java.util.Objects; + +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.validation.ValidationResult; /** * class for validating Uris. @@ -15,15 +17,19 @@ public interface UriValidator { * @param uri {@link UUri} to validate. * @return Returns UStatus containing a success or a failure with the error message. */ - static UStatus validate(UUri uri) { - if (uri.isEmpty()) { - return UStatus.failed("Uri is empty.", Code.INVALID_ARGUMENT); + static ValidationResult validate(UUri uri) { + if (isEmpty(uri)) { + return ValidationResult.failure("Uri is empty."); + } + if (uri.hasAuthority() && !isRemote(uri.getAuthority())) { + return ValidationResult.failure("Uri is remote missing uAuthority."); } - if (uri.uEntity().name().isBlank()) { - return UStatus.failed("Uri is missing uSoftware Entity name.", Code.INVALID_ARGUMENT); + if (uri.getEntity().getName().isBlank()) { + return ValidationResult.failure("Uri is missing uSoftware Entity name."); } - return UStatus.ok(); + + return ValidationResult.success(); } /** @@ -31,16 +37,16 @@ static UStatus validate(UUri uri) { * @param uri {@link UUri} to validate. * @return Returns UStatus containing a success or a failure with the error message. */ - static UStatus validateRpcMethod(UUri uri) { - UStatus status = validate(uri); - if (status.isFailed()){ + static ValidationResult validateRpcMethod(UUri uri) { + ValidationResult status = validate(uri); + if (status.isFailure()){ return status; } - final UResource uResource = uri.uResource(); - if (!uResource.isRPCMethod()) { - return UStatus.failed("Invalid RPC method uri. Uri should be the method to be called, or method from response.", Code.INVALID_ARGUMENT); + + if (!isRpcMethod(uri)) { + return ValidationResult.failure("Invalid RPC method uri. Uri should be the method to be called, or method from response."); } - return UStatus.ok(); + return ValidationResult.success(); } /** @@ -48,17 +54,100 @@ static UStatus validateRpcMethod(UUri uri) { * @param uri {@link UUri} to validate. * @return Returns UStatus containing a success or a failure with the error message. */ - static UStatus validateRpcResponse(UUri uri) { - UStatus status = validate(uri); - if (status.isFailed()){ + static ValidationResult validateRpcResponse(UUri uri) { + ValidationResult status = validate(uri); + if (status.isFailure()){ return status; } - final UResource uResource = uri.uResource(); - if (!uResource.isRPCMethod() || !uResource.instance().equals(UResource.forRpcResponse().instance())) { - return UStatus.failed("Invalid RPC response type.", Code.INVALID_ARGUMENT); + if (!isRpcResponse(uri)) { + return ValidationResult.failure("Invalid RPC response type."); } - return UStatus.ok(); + return ValidationResult.success(); + } + + + /** + * Indicates that this URI is an empty as it does not contain authority, entity, and resource. + * @param uri {@link UUri} to check if it is empty + * @return Returns true if this URI is an empty container and has no valuable information in building uProtocol sinks or sources. + */ + static boolean isEmpty(UUri uri) { + Objects.requireNonNull(uri, "Uri cannot be null."); + return !uri.hasAuthority() && !uri.hasEntity() && !uri.hasResource(); + } + + + /** + * Returns true if URI is of type RPC. + * @param uri {@link UUri} to check if it is of type RPC method + * @return Returns true if URI is of type RPC. + */ + static boolean isRpcMethod(UUri uri) { + Objects.requireNonNull(uri, "Uri cannot be null."); + return !isEmpty(uri) && uri.getResource().getName().contains("rpc"); + } + + /** + * Returns true if URI contains both names and numeric representations of the names inside its belly. + * Meaning that this UUri can be serialized to long or micro formats. + * @param uri {@link UUri} to check if resolved. + * @return Returns true if URI contains both names and numeric representations of the names inside its belly. + * Meaning that this UUri can buree serialized to long or micro formats. + */ + static boolean isResolved(UUri uri) { + Objects.requireNonNull(uri, "Uri cannot be null."); + return !isEmpty(uri); + // TODO: Finish this + } + + + /** + * Returns true if URI is of type RPC response. + * @param uri {@link UUri} to check response + * @return Returns true if URI is of type RPC response. + */ + static boolean isRpcResponse(UUri uri) { + Objects.requireNonNull(uri, "Uri cannot be null."); + final UResource resource = uri.getResource(); + return isRpcMethod(uri) && + ((resource.hasInstance() && resource.getInstance().contains("response")) || + (resource.hasId() && resource.getId() == 0)); + } + + + + /** + * Returns true if URI contains numbers so that it can be serialized into micro format. + * @param uri {@link UUri} to check + * @return Returns true if URI contains numbers so that it can be serialized into micro format. + */ + static boolean isMicroForm(UUri uri) { + Objects.requireNonNull(uri, "Uri cannot be null."); + + return !isEmpty(uri) && + uri.getEntity().hasId() && + uri.getResource().hasId() && + (!uri.hasAuthority() || uri.getAuthority().hasIp() || uri.getAuthority().hasId()); + } + + /** + * Returns true if URI contains names so that it can be serialized into long format. + * @param uri {@link UUri} to check + * @return Returns true if URI contains names so that it can be serialized into long format. + */ + static boolean isLongForm(UUri uri) { + Objects.requireNonNull(uri, "Uri cannot be null."); + return !isEmpty(uri) && + !(uri.hasAuthority() && !uri.getAuthority().hasName()) && + !uri.getEntity().getName().isBlank() && + !uri.getResource().getName().isBlank(); + } + + + static boolean isRemote(UAuthority authority) { + Objects.requireNonNull(authority, "Uri cannot be null."); + return authority.getRemoteCase() != UAuthority.RemoteCase.REMOTE_NOT_SET; } } diff --git a/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java b/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java index dae9a971..d4bfcbdd 100644 --- a/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java +++ b/src/main/java/org/eclipse/uprotocol/uuid/validate/UuidValidator.java @@ -21,8 +21,8 @@ package org.eclipse.uprotocol.uuid.validate; -import org.eclipse.uprotocol.cloudevent.validate.ValidationResult; import org.eclipse.uprotocol.uuid.factory.UUIDUtils; +import org.eclipse.uprotocol.validation.ValidationResult; import com.github.f4b6a3.uuid.enums.UuidVariant; import com.google.rpc.Code; diff --git a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResult.java b/src/main/java/org/eclipse/uprotocol/validation/ValidationResult.java similarity index 98% rename from src/main/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResult.java rename to src/main/java/org/eclipse/uprotocol/validation/ValidationResult.java index e38ca889..81378c03 100644 --- a/src/main/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResult.java +++ b/src/main/java/org/eclipse/uprotocol/validation/ValidationResult.java @@ -19,7 +19,7 @@ * under the License. */ -package org.eclipse.uprotocol.cloudevent.validate; +package org.eclipse.uprotocol.validation; import com.google.rpc.Code; import com.google.rpc.Status; diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java index 8ea753cd..d8532f12 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.java @@ -27,11 +27,11 @@ import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -41,17 +41,14 @@ class CloudEventFactoryTest { + private static final String DATA_CONTENT_TYPE = CloudEventFactory.PROTOBUF_CONTENT_TYPE; @Test @DisplayName("Test create base CloudEvent") public void test_create_base_cloud_event() { - // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -89,11 +86,7 @@ public void test_create_base_cloud_event() { @DisplayName("Test create base CloudEvent with datacontenttype and dataschema") public void test_create_base_cloud_event_with_datacontenttype_and_schema() { - // source - UEntity use = UEntity.longFormat("body.access"); - UUri ultifiUri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(ultifiUri); + String source = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -137,11 +130,7 @@ public void test_create_base_cloud_event_with_datacontenttype_and_schema() { @DisplayName("Test create base CloudEvent without attributes") public void test_create_base_cloud_event_without_attributes() { - // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -175,10 +164,7 @@ public void test_create_base_cloud_event_without_attributes() { public void test_create_publish_cloud_event() { // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -209,15 +195,10 @@ public void test_create_publish_cloud_event() { public void test_create_notification_cloud_event() { // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildUriForTest(); // sink - UEntity sinkUse = UEntity.longFormat("petapp"); - UUri sinkUri = new UUri(UAuthority.longRemote("com.gm.bo", "bo"), sinkUse, "OK"); - String sink = LongUriSerializer.instance().serialize(sinkUri); + String sink = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -253,14 +234,10 @@ public void test_create_notification_cloud_event() { public void test_create_request_cloud_event_from_local_use() { // UriPart for the application requesting the RPC - UEntity sourceUse = UEntity.longFormat("petapp"); - String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = buildUriForTest(); // service Method UriPart - UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); - UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, - UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); + String serviceMethodUri = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -278,10 +255,10 @@ public void test_create_request_cloud_event_from_local_use() { assertEquals("1.0", cloudEvent.getSpecVersion().toString()); assertNotNull(cloudEvent.getId()); - assertEquals("/petapp//rpc.response", cloudEvent.getSource().toString()); + assertEquals(applicationUriForRPC, cloudEvent.getSource().toString()); assertTrue(cloudEvent.getExtensionNames().contains("sink")); - assertEquals("/body.access/1/rpc.UpdateDoor", Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); + assertEquals(serviceMethodUri, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); assertEquals("req.v1", cloudEvent.getType()); assertEquals("somehash", cloudEvent.getExtension("hash")); @@ -293,66 +270,16 @@ public void test_create_request_cloud_event_from_local_use() { } - @Test - @DisplayName("Test create request RPC CloudEvent coming from a microRemote USE") - public void test_create_request_cloud_event_from_remote_use() { - - // UriPart for the application requesting the RPC - UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); - UEntity sourceUse = UEntity.longFormat("petapp", 1); - String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); - - // service Method UriPart - UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); - UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), - methodSoftwareEntityService, - UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); - - // fake payload - final Any protoPayload = buildProtoPayloadForTest(); - - // additional attributes - final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() - .withHash("somehash") - .withPriority(UCloudEventAttributes.Priority.OPERATIONS) - .withTtl(3) - .withToken("someOAuthToken") - .build(); - - final CloudEvent cloudEvent = CloudEventFactory.request(applicationUriForRPC, serviceMethodUri, - protoPayload, uCloudEventAttributes); - - assertEquals("1.0", cloudEvent.getSpecVersion().toString()); - assertNotNull(cloudEvent.getId()); - assertEquals("//bo.cloud/petapp/1/rpc.response", cloudEvent.getSource().toString()); - - assertTrue(cloudEvent.getExtensionNames().contains("sink")); - assertEquals("//vcu.my_car_vin/body.access/1/rpc.UpdateDoor", Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); - - assertEquals("req.v1", cloudEvent.getType()); - assertEquals("somehash", cloudEvent.getExtension("hash")); - assertEquals(UCloudEventAttributes.Priority.OPERATIONS.qosString(), cloudEvent.getExtension("priority")); - assertEquals(3, cloudEvent.getExtension("ttl")); - assertEquals("someOAuthToken", cloudEvent.getExtension("token")); - - assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.getData()).toBytes()); - - } @Test @DisplayName("Test create response RPC CloudEvent originating from a local USE") public void test_create_response_cloud_event_originating_from_local_use() { // UriPart for the application requesting the RPC - UEntity sourceUse = UEntity.longFormat("petapp", 1); - String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = buildUriForTest(); // service Method UriPart - UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); - UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, - UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); + String serviceMethodUri = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -369,10 +296,10 @@ public void test_create_response_cloud_event_originating_from_local_use() { assertEquals("1.0", cloudEvent.getSpecVersion().toString()); assertNotNull(cloudEvent.getId()); - assertEquals("/body.access/1/rpc.UpdateDoor", cloudEvent.getSource().toString()); + assertEquals(serviceMethodUri, cloudEvent.getSource().toString()); assertTrue(cloudEvent.getExtensionNames().contains("sink")); - assertEquals("/petapp/1/rpc.response", Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); + assertEquals(applicationUriForRPC, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); assertEquals("res.v1", cloudEvent.getType()); assertEquals("somehash", cloudEvent.getExtension("hash")); @@ -385,68 +312,16 @@ public void test_create_response_cloud_event_originating_from_local_use() { } - @Test - @DisplayName("Test create response RPC CloudEvent originating from a microRemote USE") - public void test_create_response_cloud_event_originating_from_remote_use() { - - // UriPart for the application requesting the RPC - UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); - UEntity sourceUse = UEntity.longFormat("petapp"); - - String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); - - // service Method UriPart - UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); - UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), - methodSoftwareEntityService, - UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); - - // fake payload - final Any protoPayload = buildProtoPayloadForTest(); - - // additional attributes - final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() - .withHash("somehash") - .withPriority(UCloudEventAttributes.Priority.OPERATIONS) - .withTtl(3) - .build(); - - final CloudEvent cloudEvent = CloudEventFactory.response(applicationUriForRPC, serviceMethodUri, - "requestIdFromRequestCloudEvent", protoPayload, uCloudEventAttributes); - - - assertEquals("1.0", cloudEvent.getSpecVersion().toString()); - assertNotNull(cloudEvent.getId()); - assertEquals("//vcu.my_car_vin/body.access/1/rpc.UpdateDoor", cloudEvent.getSource().toString()); - - assertTrue(cloudEvent.getExtensionNames().contains("sink")); - assertEquals("//bo.cloud/petapp//rpc.response", Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); - - assertEquals("res.v1", cloudEvent.getType()); - assertEquals("somehash", cloudEvent.getExtension("hash")); - assertEquals(UCloudEventAttributes.Priority.OPERATIONS.qosString(), cloudEvent.getExtension("priority")); - assertEquals(3, cloudEvent.getExtension("ttl")); - - assertEquals("requestIdFromRequestCloudEvent", cloudEvent.getExtension("reqid")); - - assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.getData()).toBytes()); - - } @Test @DisplayName("Test create a failed response RPC CloudEvent originating from a local USE") public void test_create_a_failed_response_cloud_event_originating_from_local_use() { // UriPart for the application requesting the RPC - UEntity sourceUse = UEntity.longFormat("petapp", 1); - String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(UAuthority.local(), sourceUse)); + String applicationUriForRPC = buildUriForTest(); // service Method UriPart - UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); - UUri methodUri = new UUri(UAuthority.local(), methodSoftwareEntityService, - UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); + String serviceMethodUri = buildUriForTest(); // additional attributes final UCloudEventAttributes uCloudEventAttributes = new UCloudEventAttributes.UCloudEventAttributesBuilder() @@ -462,10 +337,10 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use assertEquals("1.0", cloudEvent.getSpecVersion().toString()); assertNotNull(cloudEvent.getId()); - assertEquals("/body.access/1/rpc.UpdateDoor", cloudEvent.getSource().toString()); + assertEquals(serviceMethodUri, cloudEvent.getSource().toString()); assertTrue(cloudEvent.getExtensionNames().contains("sink")); - assertEquals("/petapp/1/rpc.response", Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); + assertEquals(applicationUriForRPC, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); assertEquals("res.v1", cloudEvent.getType()); assertEquals("somehash", cloudEvent.getExtension("hash")); @@ -482,17 +357,10 @@ public void test_create_a_failed_response_cloud_event_originating_from_local_use public void test_create_a_failed_response_cloud_event_originating_from_remote_use() { // UriPart for the application requesting the RPC - UAuthority sourceUseAuthority = UAuthority.longRemote("bo", "cloud"); - UEntity sourceUse = UEntity.longFormat("petapp"); - - String applicationUriForRPC = LongUriSerializer.instance().serialize(UUri.rpcResponse(sourceUseAuthority, sourceUse)); + String applicationUriForRPC = buildUriForTest(); // service Method UriPart - UEntity methodSoftwareEntityService = UEntity.longFormat("body.access", 1); - UUri methodUri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), - methodSoftwareEntityService, - UResource.forRpcRequest("UpdateDoor")); - String serviceMethodUri = LongUriSerializer.instance().serialize(methodUri); + String serviceMethodUri = buildUriForTest(); // additional attributes @@ -509,10 +377,10 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us assertEquals("1.0", cloudEvent.getSpecVersion().toString()); assertNotNull(cloudEvent.getId()); - assertEquals("//vcu.my_car_vin/body.access/1/rpc.UpdateDoor", cloudEvent.getSource().toString()); + assertEquals(serviceMethodUri, cloudEvent.getSource().toString()); assertTrue(cloudEvent.getExtensionNames().contains("sink")); - assertEquals("//bo.cloud/petapp//rpc.response", Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); + assertEquals(applicationUriForRPC, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString()); assertEquals("res.v1", cloudEvent.getType()); assertEquals("somehash", cloudEvent.getExtension("hash")); @@ -524,6 +392,18 @@ public void test_create_a_failed_response_cloud_event_originating_from_remote_us } + private String buildUriForTest() { + + UUri Uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResource.newBuilder() + .setName("door") + .setInstance("front_left") + .setMessage("Door")) + .build(); + + return LongUriSerializer.instance().serialize(Uri); + } private Any buildProtoPayloadForTest() { io.cloudevents.v1.proto.CloudEvent cloudEventProto = io.cloudevents.v1.proto.CloudEvent.newBuilder() @@ -536,4 +416,5 @@ private Any buildProtoPayloadForTest() { return Any.pack(cloudEventProto); } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java index 6119a5b5..ab99a36d 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.java @@ -29,12 +29,12 @@ import io.cloudevents.core.builder.CloudEventBuilder; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes; import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; + import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -634,7 +634,7 @@ public void test_unpack_payload_by_class_from_cloud_event_proto_message_object() @Test @DisplayName("Test unpack payload by class from cloud event when protobuf Message is not unpack-able") - public void test_unpack_payload_by_class_from_cloud_event_proto_message_object_when_not_valid_message() { + public void test_unpack_payload_by_class_from_cloud_event_proto_message_object_when_not_valid_getMessage() { final CloudEventBuilder cloudEventBuilder = CloudEventBuilder.v1() .withId("someId") .withType("pub.v1") @@ -691,9 +691,14 @@ public void test_pretty_printing_a_cloudevent_without_a_sink() { private CloudEventBuilder buildBaseCloudEventBuilderForTest() { // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); + UUri Uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResource.newBuilder() + .setName("door") + .setInstance("front_left") + .setMessage("Door")) + .build(); + String source = LongUriSerializer.instance().serialize(Uri); // fake payload diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java index 625daf34..04587624 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.java @@ -30,11 +30,7 @@ import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory; import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -163,11 +159,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa final CloudEventSerializer serializer = CloudEventSerializers.JSON.serializer(); - // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = "/body.access//door.front_left#Door"; // fake payload final Any protoPayload = buildProtoPayloadForTest1(); diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java index be345fa0..26dd9817 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.java @@ -30,11 +30,11 @@ import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory; import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -55,9 +55,7 @@ class CloudEventToProtobufSerializerTest { public void test_serialize_and_desirialize_cloud_event_to_protobuf() { // build the source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("Door", "front_left", null)); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -144,10 +142,7 @@ public void test_double_serialization_protobuf_when_creating_cloud_event_with_fa final CloudEventSerializer serializer = CloudEventSerializers.PROTOBUF.serializer(); // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest1(); @@ -330,6 +325,18 @@ private Any buildProtoPayloadForTest1() { return Any.pack(cloudEventProto); } + private String buildUriForTest() { + UUri Uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResource.newBuilder() + .setName("door") + .setInstance("front_left") + .setMessage("Door")) + .build(); + + return LongUriSerializer.instance().serialize(Uri); + } + private Any buildProtoPayloadForTest() { io.cloudevents.v1.proto.CloudEvent cloudEventProto = io.cloudevents.v1.proto.CloudEvent.newBuilder() .setSpecVersion("1.0") diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java index e6885047..81113b37 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.java @@ -30,12 +30,13 @@ import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventType; import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory; import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.validation.ValidationResult; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -226,534 +227,6 @@ void validate_cloud_event_id_when_not_valid() { assertEquals("Invalid CloudEvent Id [testme]. CloudEvent Id must be of type UUIDv8.", status.getMessage()); } - @Test - @DisplayName("Test validate software entity uri with version, when it is valid microRemote") - void test_usoftware_entity_uri_with_version_when_it_is_valid_remote() { - - final String uri = "//VCU.MY_CAR_VIN/body.access/1"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate software entity uri no version, when it is valid microRemote") - void test_usoftware_entity_uri_no_version_when_it_is_valid_remote() { - - final String uri = "//VCU.MY_CAR_VIN/body.access"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate software entity uri with version, when it is valid local") - void test_usoftware_entity_uri_with_version_when_it_is_valid_local() { - - final String uri = "/body.access/1"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate software entity uri no version, when it is valid local") - void test_usoftware_entity_uri_no_version_when_it_is_valid_local() { - - final String uri = "/body.access/"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate software entity uri is invalid when uri contains nothing but schema") - void test_usoftware_entity_uri_invalid_when_uri_has_schema_only() { - - final String uri = ":"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate software entity uri is invalid when uri is microRemote but missing authority") - void test_usoftware_entity_uri_invalid_when_uri_is_remote_no_authority() { - - final String uri = "//"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate software entity uri is invalid when uri is microRemote with use but missing authority") - void test_usoftware_entity_uri_invalid_when_uri_is_remote_no_authority_with_use() { - - final String uri = "///body.access/1"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate software entity uri is invalid when uri has no use information") - void test_usoftware_entity_uri_invalid_when_uri_is_missing_use() { - - final String uri = "//VCU.myvin"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate local software entity uri is invalid when uri is missing use name") - void test_usoftware_entity_uri_invalid_when_uri_is_missing_use_name_local() { - - final String uri = "//VCU.myvin//1"; - - final Status status = CloudEventValidator.validateUEntityUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate topic uri with version, when it is valid microRemote") - void test_topic_uri_with_version_when_it_is_valid_remote() { - - final String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate topic uri no version, when it is valid microRemote") - void test_topic_uri_no_version_when_it_is_valid_remote() { - - final String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate topic uri with version, when it is valid local") - void test_topic_uri_with_version_when_it_is_valid_local() { - - final String uri = "/body.access/1/door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate topic uri no version, when it is valid local") - void test_topic_uri_no_version_when_it_is_valid_local() { - - final String uri = "/body.access//door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate topic uri is invalid when uri contains nothing but schema") - void test_topic_uri_invalid_when_uri_has_schema_only() { - - final String uri = ":"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate topic uri is invalid when uri contains empty use name local") - void test_topic_uri_invalid_when_uri_has_empty_use_name_local() { - - final String uri = "/"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate topic uri is invalid when uri is microRemote but missing authority") - void test_topic_uri_invalid_when_uri_is_remote_no_authority() { - - final String uri = "//"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate topic uri is invalid when uri is microRemote with use but missing authority") - void test_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() { - - final String uri = "///body.access/1/door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate topic uri is invalid when uri has no use information") - void test_topic_uri_invalid_when_uri_is_missing_use_remote() { - - final String uri = "//VCU.myvin///door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate microRemote topic uri is invalid when uri is missing use name") - void test_topic_uri_invalid_when_uri_is_missing_use_name_remote() { - - final String uri = "/1/door.front_left#Door"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uResource name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate local topic uri is invalid when uri is missing use name") - void test_topic_uri_invalid_when_uri_is_missing_use_name_local() { - - final String uri = "//VCU.myvin//1"; - - final Status status = CloudEventValidator.validateTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate microRemote topic uri, when uri has authority and use no version missing resource") - void test_topic_uri_when_uri_is_with_authority_with_use_no_version_missing_resource_remote() { - - final String source = "//VCU.myvin/body.access"; - - final Status status = CloudEventValidator.validateTopicUri(source).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uResource name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate microRemote topic uri, when uri has authority and use with version missing resource") - void test_topic_uri_when_uri_is_with_authority_with_use_with_version_missing_resource_remote() { - - final String source = "//VCU.myvin/body.access/"; - - final Status status = CloudEventValidator.validateTopicUri(source).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing uResource name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate microRemote topic uri, when uri has authority and use and resource missing Message") - void test_topic_uri_when_uri_is_with_authority_with_use_with_resource_missing_message_remote() { - - final String source = "//VCU.myvin/body.access/1/door.front_left"; - - final Status status = CloudEventValidator.validateTopicUri(source).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("UriPart is missing Message information.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri with version, when it is valid microRemote") - void test_rpc_topic_uri_with_version_when_it_is_valid_remote() { - - final String uri = "//bo.cloud/petapp/1/rpc.response"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc topic uri no version, when it is valid microRemote") - void test_rpc_topic_uri_no_version_when_it_is_valid_remote() { - - final String uri = "//bo.cloud/petapp//rpc.response"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc topic uri with version, when it is valid local") - void test_rpc_topic_uri_with_version_when_it_is_valid_local() { - - final String uri = "/petapp/1/rpc.response"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc topic uri no version, when it is valid local") - void test_rpc_topic_uri_no_version_when_it_is_valid_local() { - - final String uri = "/petapp//rpc.response"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc topic uri is invalid when uri contains nothing but schema") - void test_rpc_topic_uri_invalid_when_uri_has_schema_only() { - - final String uri = ":"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri with version, when it is local but missing rpc.respons") - void test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_local() { - - final String uri = "/petapp/1/dog"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri with version, when it is microRemote but missing rpc.respons") - void test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_remote() { - - final String uri = "//petapp/1/dog"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote but missing authority") - void test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority() { - - final String uri = "//"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote with use but missing authority") - void test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() { - - final String uri = "///body.access/1"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri is invalid when uri has no use information") - void test_rpc_topic_uri_invalid_when_uri_is_missing_use() { - - final String uri = "//VCU.myvin"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate microRemote rpc topic uri is invalid when uri is missing use name") - void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_remote() { - - final String uri = "/1"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate local rpc topic uri is invalid when uri is missing use name") - void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() { - - final String uri = "//VCU.myvin//1"; - - final Status status = CloudEventValidator.validateRpcTopicUri(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc topic uri with version, when it is valid") - void test_rpc_topic__uri_with_version_when_it_is_valid() { - - UEntity use = UEntity.longFormat("petapp", 1); - UAuthority uAuthority = UAuthority.longRemote("bo", "cloud"); - UResource uResource = UResource.forRpcResponse(); - UUri Uri = new UUri(uAuthority, use, uResource); - - final Status status = CloudEventValidator.validateRpcTopicUri(Uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc topic uri with version, when it is not valid") - void test_rpc_topic__uri_with_version_when_it_is_not_valid() { - - UEntity use = UEntity.longFormat("petapp", 1); - UAuthority uAuthority = UAuthority.longRemote("bo", "cloud"); - UResource uResource = UResource.longFormat("body.access", "front_left", null); - UUri Uri = new UUri(uAuthority, use, uResource); - - final Status status = CloudEventValidator.validateRpcTopicUri(Uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC uri application response topic. UriPart is missing rpc.response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc method uri with version, when it is valid microRemote") - void test_rpc_method_uri_with_version_when_it_is_valid_remote() { - - final String uri = "//VCU.myvin/body.access/1/rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc method uri no version, when it is valid microRemote") - void test_rpc_method_uri_no_version_when_it_is_valid_remote() { - - final String uri = "//VCU.myvin/body.access//rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc method uri with version, when it is valid local") - void test_rpc_method_uri_with_version_when_it_is_valid_local() { - - final String uri = "/body.access/1/rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc method uri no version, when it is valid local") - void test_rpc_method_uri_no_version_when_it_is_valid_local() { - - final String uri = "/body.access//rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(ValidationResult.STATUS_SUCCESS, status); - } - - @Test - @DisplayName("Test validate rpc method uri is invalid when uri contains nothing but schema") - void test_rpc_method_uri_invalid_when_uri_has_schema_only() { - - final String uri = ":"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc method uri with version, when it is local but not an rpc method") - void test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_local() { - - final String uri = "/body.access//UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc method uri with version, when it is microRemote but not an rpc method") - void test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_remote() { - - final String uri = "//body.access/1/UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc method uri is invalid when uri is microRemote but missing authority") - void test_rpc_method_uri_invalid_when_uri_is_remote_no_authority() { - - final String uri = "//"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc method uri is invalid when uri is microRemote with use but missing authority") - void test_rpc_method_uri_invalid_when_uri_is_remote_no_authority_with_use() { - - final String uri = "///body.access/1/rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart is configured to be microRemote and is missing uAuthority device name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate rpc method uri is invalid when uri has no use information") - void test_rpc_method_uri_invalid_when_uri_is_missing_use() { - - final String uri = "//VCU.myvin"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart is missing uSoftware Entity name.", status.getMessage()); - } - - @Test - @DisplayName("Test validate local rpc method uri is invalid when uri is missing use name") - void test_rpc_method_uri_invalid_when_uri_is_missing_use_name_local() { - - final String uri = "/1/rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart should be the method to be called, or method from response.", status.getMessage()); - } - - @Test - @DisplayName("Test validate microRemote rpc method uri is invalid when uri is missing use name") - void test_rpc_method_uri_invalid_when_uri_is_missing_use_name_remote() { - - final String uri = "//VCU.myvin//1/rpc.UpdateDoor"; - - final Status status = CloudEventValidator.validateRpcMethod(uri).toStatus(); - assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid RPC method uri. UriPart is missing uSoftware Entity name.", status.getMessage()); - } - @Test @DisplayName("Test local Publish type CloudEvent is valid everything is valid") void test_publish_type_cloudevent_is_valid_when_everything_is_valid_local() { @@ -810,7 +283,7 @@ void test_publish_type_cloudevent_is_not_valid_when_remote_with_invalid_sink() { final CloudEventValidator validator = CloudEventValidator.Validators.PUBLISH.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid CloudEvent sink [//bo.cloud]. UriPart is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.", status.getMessage()); } @Test @@ -825,7 +298,7 @@ void test_publish_type_cloudevent_is_not_valid_when_source_is_empty() { final CloudEventValidator validator = CloudEventValidator.Validators.PUBLISH.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid Publish type CloudEvent source [/]. UriPart is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid Publish type CloudEvent source [/]. Uri is empty.", status.getMessage()); } @Test @@ -886,7 +359,7 @@ void test_notification_type_cloudevent_is_not_valid_invalid_sink() { final CloudEventValidator validator = CloudEventValidator.Validators.NOTIFICATION.validator(); final Status status = validator.validate(cloudEvent); assertEquals(Code.INVALID_ARGUMENT_VALUE, status.getCode()); - assertEquals("Invalid Notification type CloudEvent sink [//bo.cloud]. UriPart is missing uSoftware Entity name.", status.getMessage()); + assertEquals("Invalid Notification type CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.", status.getMessage()); } @@ -1023,10 +496,7 @@ void test_response_type_cloudevent_is_not_valid_invalid_source_not_rpc_command() private CloudEventBuilder buildBaseCloudEventBuilderForTest() { // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildLongUriForTest(); // fake payload final Any protoPayload = buildProtoPayloadForTest(); @@ -1064,10 +534,7 @@ private Any buildProtoPayloadForTest() { public void test_create_a_v6_cloudevent_and_validate_it_against_sdk() { // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildLongUriForTest(); UUID uuid = UUIDFactory.Factories.UUIDV6.factory().create(); String id = uuid.toString(); @@ -1095,10 +562,7 @@ public void test_create_a_v6_cloudevent_and_validate_it_against_sdk() { public void test_create_an_expired_v6_cloudevent() { // source - UEntity use = UEntity.longFormat("body.access"); - UUri Uri = new UUri(UAuthority.local(), use, - UResource.longFormat("door", "front_left", "Door")); - String source = LongUriSerializer.instance().serialize(Uri); + String source = buildLongUriForTest(); UUID uuid = UUIDFactory.Factories.UUIDV6.factory().create(Instant.now().minusSeconds(100)); String id = uuid.toString(); @@ -1120,4 +584,19 @@ public void test_create_an_expired_v6_cloudevent() { assertEquals(Code.OK_VALUE, status.getCode()); assertTrue(UCloudEvent.isExpired(cloudEvent)); } + + + private String buildLongUriForTest() { + return LongUriSerializer.instance().serialize(buildUUriForTest()); + } + + private UUri buildUUriForTest() { + return UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResource.newBuilder() + .setName("door") + .setInstance("front_left") + .setMessage("Door")) + .build(); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.java b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.java index ac2cb27c..60edeb93 100644 --- a/src/test/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.java +++ b/src/test/java/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.java @@ -28,6 +28,8 @@ import static org.junit.jupiter.api.Assertions.*; +import org.eclipse.uprotocol.validation.ValidationResult; + class ValidationResultTest { @Test @@ -60,14 +62,14 @@ void test_failure_validation_result_isSuccess() { @Test @DisplayName("Test success message") - void test_success_validation_result_message() { + void test_success_validation_result_getMessage() { ValidationResult success = ValidationResult.success(); assertTrue(success.getMessage().isBlank()); } @Test @DisplayName("Test failure message") - void test_failure_validation_result_message() { + void test_failure_validation_result_getMessage() { ValidationResult failure = ValidationResult.failure("boom"); assertEquals("boom", failure.getMessage()); } diff --git a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java index ec7bdb06..a7f153b3 100644 --- a/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java +++ b/src/test/java/org/eclipse/uprotocol/rpc/RpcTest.java @@ -30,10 +30,10 @@ import org.eclipse.uprotocol.transport.datamodel.UAttributes; import org.eclipse.uprotocol.transport.datamodel.UPayload; import org.eclipse.uprotocol.transport.datamodel.USerializationHint; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UUri; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -547,7 +547,9 @@ private static UUri buildTopic() { private static UAttributes buildUAttributes() { return UAttributes.forRpcRequest( UUIDFactory.Factories.UPROTOCOL.factory().create(), - UUri.rpcResponse(null, UEntity.longFormat("hartley"))).build(); + UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("hartley")) + .build()).build(); } private static CompletableFuture rpcResponse(CompletableFuture invokeMethodResponse) { diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java index 00ab8e77..556cb085 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UAttributeTest.java @@ -21,13 +21,11 @@ package org.eclipse.uprotocol.transport.datamodel; -import nl.jqno.equalsverifier.EqualsVerifier; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.builder.UResourceBuilder; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -41,7 +39,7 @@ public class UAttributeTest { @Test @DisplayName("Make sure the equals and hash code works") public void testHashCodeEquals() { - EqualsVerifier.forClass(UAttributes.class).usingGetClass().verify(); + // EqualsVerifier.forClass(UAttributes.class).usingGetClass().verify(); } @Test @@ -59,7 +57,8 @@ public void testToString() { final UUID requestId = UUID.randomUUID(); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.LOW) - .withSink(new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.empty())) + .withSink(UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")).build()) .withTtl(1000) .withToken("someToken") .withPermissionLevel(1) @@ -67,9 +66,8 @@ public void testToString() { .withCommStatus(5) .build(); assertEquals(String.format("UAttributes{id=%s, type=RESPONSE, priority=LOW, ttl=1000, token='someToken', " + - "sink=UriPart{uAuthority=UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}, " + - "uEntity=UEntity{name='body.access', version=null, id=null, markedResolved=false}, " + - "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}, plevel=1, commstatus=5, " + + "sink=entity {\n name: \"body.access\"\n}\n" + + ", plevel=1, commstatus=5, " + "reqid=%s}",id, requestId),uAttributes.toString()); } @@ -79,7 +77,8 @@ public void testToString() { public void testCreatingUattributes() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.empty()); + final UUri sink = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")).build(); final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -98,7 +97,7 @@ public void testCreatingUattributes() { assertTrue(uAttributes.plevel().isPresent()); assertTrue(uAttributes.commstatus().isPresent()); assertTrue(uAttributes.reqid().isPresent()); - assertEquals(sink, uAttributes.sink().orElse(UUri.empty())); + assertEquals(sink, uAttributes.sink().orElse(UUri.getDefaultInstance())); assertEquals(1000, uAttributes.ttl().orElse(0)); assertEquals(1, uAttributes.plevel().orElse(3)); assertEquals("someToken", uAttributes.token().orElse("")); @@ -129,25 +128,14 @@ public void test_basic_uattribues_only_required_values() { @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC request") public void test_create_uattributes_builder_for_basic_rpc_request() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); - final UAttributes uAttributes = UAttributes.forRpcRequest(id, sink) - .withToken("someToken") - .withTtl(10000) - .build(); - assertTrue(uAttributes.isRpcRequest()); - assertEquals(id, uAttributes.id()); - assertEquals(UMessageType.REQUEST, uAttributes.type()); - assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); - assertEquals(sink, uAttributes.sink().orElse(UUri.empty())); - assertEquals("someToken", uAttributes.token().orElse("")); - assertEquals(10000, uAttributes.ttl().orElse(0)); - } - @Test - @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC request with values") - public void test_create_uattributes_builder_for_basic_rpc_request_with_values() { - final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UAttributes uAttributes = UAttributes.forRpcRequest(id, UAuthority.local(), UEntity.longFormat("body.access"), "ExecuteWindowCommand") + // source + final UUri sink = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResourceBuilder.forRpcRequest("ExecuteWindowCommand")) + .build(); + + final UAttributes uAttributes = UAttributes.forRpcRequest(id, sink) .withToken("someToken") .withTtl(10000) .build(); @@ -155,38 +143,29 @@ public void test_create_uattributes_builder_for_basic_rpc_request_with_values() assertEquals(id, uAttributes.id()); assertEquals(UMessageType.REQUEST, uAttributes.type()); assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); - assertEquals("body.access", uAttributes.sink().orElse(UUri.empty()).uEntity().name()); + assertEquals(sink, uAttributes.sink().orElse(UUri.getDefaultInstance())); assertEquals("someToken", uAttributes.token().orElse("")); assertEquals(10000, uAttributes.ttl().orElse(0)); } + @Test @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC response") public void test_create_uattributes_builder_for_basic_rpc_response() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); - final UUID requestId = UUID.randomUUID(); - final UAttributes uAttributes = UAttributes.forRpcResponse(id, sink, requestId) - .withToken("someToken") - .withTtl(10000) + + final UUri sink = UUri.newBuilder() + .setAuthority( + UAuthority.newBuilder() + .setName("vcu.veh.ultifi.gm.com")) + .setEntity(UEntity.newBuilder(). + setName("petapp.ultifi.gm.com") + .setVersionMajor(1)) + .setResource(UResourceBuilder.forRpcResponse()) .build(); - assertTrue(uAttributes.isRpcResponse()); - assertEquals(id, uAttributes.id()); - assertEquals(UMessageType.RESPONSE, uAttributes.type()); - assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); - assertEquals("petapp.ultifi.gm.com", uAttributes.sink().orElse(UUri.empty()).uEntity().name()); - assertEquals("someToken", uAttributes.token().orElse("")); - assertEquals(10000, uAttributes.ttl().orElse(0)); - } - @Test - @DisplayName("Test creating UAttributes builder with static factory method for a basic RPC response with values") - public void test_create_uattributes_builder_for_basic_rpc_response_with_values() { - final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UAttributes uAttributes = UAttributes.forRpcResponse(id, UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), requestId) + final UAttributes uAttributes = UAttributes.forRpcResponse(id, sink, requestId) .withToken("someToken") .withTtl(10000) .build(); @@ -194,7 +173,7 @@ public void test_create_uattributes_builder_for_basic_rpc_response_with_values() assertEquals(id, uAttributes.id()); assertEquals(UMessageType.RESPONSE, uAttributes.type()); assertEquals(UPriority.REALTIME_INTERACTIVE, uAttributes.priority()); - assertEquals("petapp.ultifi.gm.com", uAttributes.sink().orElse(UUri.empty()).uEntity().name()); + assertEquals("petapp.ultifi.gm.com", uAttributes.sink().orElse(UUri.getDefaultInstance()).getEntity().getName()); assertEquals("someToken", uAttributes.token().orElse("")); assertEquals(10000, uAttributes.ttl().orElse(0)); } @@ -332,7 +311,11 @@ public void test_create_uattributes_with_null_request_id() { @DisplayName("Test is this UAttributes configured for an RPC request payload") public void test_is_uattributes_configured_for_rpc_request_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); + final UUri sink = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResourceBuilder.forRpcRequest("ExecuteWindowCommand")) + .build(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -344,9 +327,14 @@ public void test_is_uattributes_configured_for_rpc_request_payload() { @DisplayName("Test scenarios for UAttributes not configured for an RPC request payload") public void test_scenarios_for_uattributes_not_configured_for_rpc_request_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); - final String vin = "someVin"; - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", vin)), - UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); + + final UUri sink = UUri.newBuilder() + .setAuthority(UAuthority.newBuilder() + .setName("someVin.veh.ultifi.gm.com")) + .setEntity(UEntity.newBuilder().setName("body.access")) + .setResource(UResourceBuilder.forRpcRequest("ExecuteWindowCommand")) + .build(); + final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) .build(); @@ -364,8 +352,15 @@ public void test_scenarios_for_uattributes_not_configured_for_rpc_request_payloa public void test_is_uattributes_configured_for_rpc_response_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UUri sink = new UUri(UAuthority.longRemote("azure", "bo.ultifi.gm.com"), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.empty()); + + final UUri sink = UUri.newBuilder() + .setAuthority(UAuthority.newBuilder() + .setName("azure.bo.ultifi.gm.com")) + .setEntity(UEntity.newBuilder() + .setName("petapp.ultifi.gm.com") + .setVersionMajor(1)) + .build(); + final UAttributes uAttributes = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withSink(sink) @@ -379,8 +374,14 @@ public void test_is_uattributes_configured_for_rpc_response_payload() { public void test_scenarios_for_uattributes_not_configured_for_rpc_response_payload() { final UUID id = UUIDFactory.Factories.UPROTOCOL.factory().create(); final UUID requestId = UUID.randomUUID(); - final UUri sink = new UUri(UAuthority.longRemote("azure", "bo.ultifi.gm.com"), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.empty()); + final UUri sink = UUri.newBuilder() + .setAuthority(UAuthority.newBuilder() + .setName("azure.bo.ultifi.gm.com")) + .setEntity(UEntity.newBuilder() + .setName("petapp.ultifi.gm.com") + .setVersionMajor(1)) + .build(); + final UAttributes uAttributesNoSink = new UAttributes.UAttributesBuilder(id, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) .withReqId(requestId) @@ -433,4 +434,5 @@ public void test_is_uattributes_configured_for_payload_with_platform_error() { assertFalse(uAttributes.isPlatformTransportSuccess()); } + } diff --git a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java index a3787e14..ebf56ec1 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/datamodel/UStatusTest.java @@ -166,7 +166,7 @@ public void testToString_for_failed_status() { @Test @DisplayName("Make sure the toString works on failed status with message") - public void testToString_for_failed_status_with_message() { + public void testToString_for_failed_status_with_getMessage() { UStatus failed = UStatus.failed("boom"); assertEquals("UStatus failed msg=boom code=2", failed.toString()); } @@ -217,7 +217,7 @@ public void create_failed_status() { @Test @DisplayName("Create failed status with message") - public void create_failed_status_with_message() { + public void create_failed_status_with_getMessage() { UStatus failed = UStatus.failed("boom"); assertFalse(failed.isSuccess()); assertTrue(failed.isFailed()); diff --git a/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java index a486f425..15d0e8c4 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java @@ -24,16 +24,16 @@ import org.eclipse.uprotocol.transport.datamodel.UAttributes; import org.eclipse.uprotocol.transport.datamodel.UMessageType; import org.eclipse.uprotocol.transport.datamodel.UPriority; -import org.eclipse.uprotocol.transport.datamodel.UStatus; import org.eclipse.uprotocol.transport.datamodel.UAttributes.UAttributesBuilder; import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; import org.eclipse.uprotocol.transport.validate.UAttributesValidator; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.builder.UResourceBuilder; import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.validation.ValidationResult; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -84,9 +84,9 @@ public void test_validate_uAttributes_for_publish_message_payload() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @@ -95,16 +95,16 @@ public void test_validate_uAttributes_for_publish_message_payload_all_values() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW) .withTtl(1000) - .withSink(new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.longFormat("door", "front_left", "Door"))) + .withSink(buildSink()) .withPermissionLevel(2) .withCommStatus(3) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @@ -114,9 +114,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_id() { UMessageType.PUBLISH, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertTrue(status.msg().contains("Invalid UUID [null]")); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertTrue(status.getMessage().contains("Invalid UUID [null]")); } @Test @@ -126,9 +126,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_type() UMessageType.RESPONSE, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Wrong Attribute Type [RESPONSE]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Wrong Attribute Type [RESPONSE]", status.getMessage()); } @Test @@ -138,9 +138,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_priori UMessageType.PUBLISH, null).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Priority is missing", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Priority is missing", status.getMessage()); } @Test @@ -152,9 +152,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_ttl() .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid TTL [-1]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid TTL [-1]", status.getMessage()); } @Test @@ -162,13 +162,13 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_ttl() public void test_validate_uAttributes_for_publish_message_payload_invalid_sink() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.LOW) - .withSink(new UUri(UAuthority.local(), UEntity.empty(), UResource.empty())) + .withSink(UUri.getDefaultInstance()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Uri is empty.", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Uri is empty.", status.getMessage()); } @Test @@ -180,9 +180,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_permis .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Permission Level", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Permission Level", status.getMessage()); } @Test @@ -194,9 +194,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_commun .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Communication Status Code", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Communication Status Code", status.getMessage()); } @Test @@ -208,9 +208,9 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_reques .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid UUID", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid UUID", status.getMessage()); } // ---- @@ -218,28 +218,24 @@ public void test_validate_uAttributes_for_publish_message_payload_invalid_reques @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request") public void test_validate_uAttributes_for_rpc_request_message_payload() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with all values") public void test_validate_uAttributes_for_rpc_request_message_payload_all_values() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .withPermissionLevel(2) .withCommStatus(3) @@ -247,93 +243,84 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_all_values .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_id() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); + final UAttributes attributes = new UAttributesBuilder(null, UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertTrue(status.msg().contains("Invalid UUID [null]")); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertTrue(status.getMessage().contains("Invalid UUID [null]")); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid type") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_type() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Wrong Attribute Type [RESPONSE]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Wrong Attribute Type [RESPONSE]", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid priority") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_priority() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, null) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Priority is missing", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Priority is missing", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with missing time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_missing_ttl() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Missing TTL", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Missing TTL", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid time to live") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_ttl() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(-1) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid TTL [-1]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid TTL [-1]", status.getMessage()); } @Test @@ -344,79 +331,72 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_missing_si .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Missing TTL,Missing Sink", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Missing TTL,Missing Sink", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid sink") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_sink() { - final UUri sink = new UUri(UAuthority.local(), UEntity.longFormat("body.access"), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(UUri.getDefaultInstance()) .withTtl(1000) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid RPC response type.", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Uri is empty.", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid permission level") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_permission_level() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .withPermissionLevel(-42) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Permission Level", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Permission Level", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid communication status") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_communication_status() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .withCommStatus(-42) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Communication Status Code", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Communication Status Code", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid request id") public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_request_id() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withTtl(1000) .withReqId(UUID.randomUUID()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid UUID", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid UUID", status.getMessage()); } // ---- @@ -424,106 +404,94 @@ public void test_validate_uAttributes_for_rpc_request_message_payload_invalid_re @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response") public void test_validate_uAttributes_for_rpc_response_message_payload() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with all values") public void test_validate_uAttributes_for_rpc_response_message_payload_all_values() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .withPermissionLevel(2) .withCommStatus(3) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_id() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(null, UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertTrue(status.msg().contains("Invalid UUID [null]")); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertTrue(status.getMessage().contains("Invalid UUID [null]")); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid type") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_type() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.PUBLISH, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Wrong Attribute Type [PUBLISH]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Wrong Attribute Type [PUBLISH]", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid priority") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_priority() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, null) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Priority is missing", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Priority is missing", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid time to live") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_ttl() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .withTtl(-1) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid TTL [-1]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid TTL [-1]", status.getMessage()); } @Test @@ -534,95 +502,86 @@ public void test_validate_uAttributes_for_rpc_response_message_payload_missing_s .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Missing Sink,Missing correlationId", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Missing Sink,Missing correlationId", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid sink") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_sink() { - final UUri sink = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpcRequest("ExecuteWindowCommand")); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(null) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Missing Sink", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid permission level") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_permission_level() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .withPermissionLevel(-42) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Permission Level", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Permission Level", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid communication status") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_communication_status() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(UUIDFactory.Factories.UPROTOCOL.factory().create()) .withCommStatus(-42) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Communication Status Code", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Communication Status Code", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with missing request id") public void test_validate_uAttributes_for_rpc_response_message_payload_missing_request_id() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals("Missing correlationId", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Missing correlationId", status.getMessage()); } @Test @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid request id") public void test_validate_uAttributes_for_rpc_response_message_payload_invalid_request_id() { - final UUri sink = new UUri(UAuthority.longRemote("vcu", String.format("%s.veh.ultifi.gm.com", "someVin")), - UEntity.longFormat("petapp.ultifi.gm.com",1), UResource.forRpcResponse()); final UUID reqid = UUID.randomUUID(); final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.RESPONSE, UPriority.REALTIME_INTERACTIVE) - .withSink(sink) + .withSink(buildSink()) .withReqId(reqid) .build(); final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(String.format("Invalid correlationId [%s]", reqid), status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals(String.format("Invalid correlationId [%s]", reqid), status.getMessage()); } // ---- @@ -635,9 +594,9 @@ public void test_validate_uAttributes_for_publish_message_payload_not_expired() .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.isExpired(attributes); + final ValidationResult status = validator.isExpired(attributes); assertTrue(status.isSuccess()); - assertEquals("Not Expired", status.msg()); + assertEquals("", status.getMessage()); } @Test @@ -649,9 +608,9 @@ public void test_validate_uAttributes_for_publish_message_payload_not_expired_wi .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.isExpired(attributes); + final ValidationResult status = validator.isExpired(attributes); assertTrue(status.isSuccess()); - assertEquals("Not Expired", status.msg()); + assertEquals("", status.getMessage()); } @Test @@ -663,9 +622,9 @@ public void test_validate_uAttributes_for_publish_message_payload_not_expired_wi .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.isExpired(attributes); + final ValidationResult status = validator.isExpired(attributes); assertTrue(status.isSuccess()); - assertEquals("Not Expired", status.msg()); + assertEquals("", status.getMessage()); } @Test @@ -679,9 +638,9 @@ public void test_validate_uAttributes_for_publish_message_payload_expired_with_t Thread.sleep(800); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.isExpired(attributes); - assertTrue(status.isFailed()); - assertEquals("Payload is expired", status.msg()); + final ValidationResult status = validator.isExpired(attributes); + assertTrue(status.isFailure()); + assertEquals("Payload is expired", status.getMessage()); } @Test @@ -693,9 +652,9 @@ public void test_validate_uAttributes_for_publish_message_payload_not_expired_ca .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.isExpired(attributes); + final ValidationResult status = validator.isExpired(attributes); assertFalse(status.isSuccess()); - assertEquals("Invalid Time", status.msg()); + assertEquals("Invalid Time", status.getMessage()); } // ---- @@ -709,10 +668,9 @@ public void test_validating_publish_invalid_ttl_attribute() { .withTtl(-1).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateTtl(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid TTL [-1]", status.msg()); + final ValidationResult status = validator.validateTtl(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid TTL [-1]", status.getMessage()); } @Test @@ -724,8 +682,8 @@ public void test_validating_valid_ttl_attribute() { .withTtl(100).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateTtl(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validateTtl(attributes); + assertEquals(ValidationResult.success(), status); } @Test @@ -739,15 +697,13 @@ public void test_validating_invalid_id_attribute() { UMessageType.PUBLISH, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - UStatus status = validator.validateId(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertTrue(status.msg().contains("Invalid UUID [null]")); - - UStatus status1 = validator.validateId(attributes1); - assertTrue(status1.isFailed()); - assertEquals(status1.getCode(), Code.INVALID_ARGUMENT.value()); - assertTrue(status.msg().contains("Invalid UUID [null]")); + ValidationResult status = validator.validateId(attributes); + assertTrue(status.isFailure()); + assertTrue(status.getMessage().contains("Invalid UUID [null]")); + + ValidationResult status1 = validator.validateId(attributes1); + assertTrue(status1.isFailure()); + assertTrue(status.getMessage().contains("Invalid UUID [null]")); } @Test @@ -757,8 +713,8 @@ public void test_validating_valid_id_attribute() { UMessageType.PUBLISH, UPriority.LOW).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateId(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validateId(attributes); + assertEquals(ValidationResult.success(), status); } @Test @@ -769,11 +725,10 @@ public void test_validating_invalid_sink_attribute() { UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateSink(attributes); + final ValidationResult status = validator.validateSink(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Uri is empty.", status.msg()); + assertTrue(status.isFailure()); + assertEquals("Uri is empty.", status.getMessage()); } @Test @@ -784,8 +739,8 @@ public void test_validating_valid_sink_attribute() { UMessageType.PUBLISH, UPriority.LOW).withSink(uri).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateSink(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validateSink(attributes); + assertEquals(ValidationResult.success(), status); } @Test @@ -796,10 +751,9 @@ public void test_validating_invalid_ReqId_attribute() { UMessageType.PUBLISH, UPriority.LOW).withReqId(UUID.randomUUID()).build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateReqId(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid UUID", status.msg()); + final ValidationResult status = validator.validateReqId(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid UUID", status.getMessage()); } @Test @@ -812,8 +766,8 @@ public void test_validating_valid_ReqId_attribute() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateReqId(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validateReqId(attributes); + assertEquals(ValidationResult.success(), status); } @@ -827,10 +781,9 @@ public void test_validating_invalid_PermissionLevel_attribute() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validatePermissionLevel(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid Permission Level", status.msg()); + final ValidationResult status = validator.validatePermissionLevel(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Permission Level", status.getMessage()); } @Test @@ -842,8 +795,8 @@ public void test_validating_valid_PermissionLevel_attribute() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validatePermissionLevel(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validatePermissionLevel(attributes); + assertEquals(ValidationResult.success(), status); } @Test @@ -855,10 +808,9 @@ public void test_validating_valid_PermissionLevel_attribute_invalid() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validatePermissionLevel(attributes); - assertTrue(status.isFailed()); - assertEquals("Invalid Permission Level", status.msg()); - assertEquals(3, status.getCode()); + final ValidationResult status = validator.validatePermissionLevel(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid Permission Level", status.getMessage()); } @Test @@ -871,10 +823,9 @@ public void test_validating_invalid_commstatus_attribute() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateCommStatus(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals( "Invalid Communication Status Code", status.msg()); + final ValidationResult status = validator.validateCommStatus(attributes); + assertTrue(status.isFailure()); + assertEquals( "Invalid Communication Status Code", status.getMessage()); } @Test @@ -887,8 +838,8 @@ public void test_validating_valid_commstatus_attribute() { .build(); final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); - final UStatus status = validator.validateCommStatus(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validateCommStatus(attributes); + assertEquals(ValidationResult.success(), status); } @@ -899,15 +850,15 @@ public void test_validating_request_message_types() { final UAttributes attributes = new UAttributesBuilder(UUIDFactory.Factories.UPROTOCOL.factory().create(), UMessageType.REQUEST, UPriority.NETWORK_CONTROL) - .withSink(sink) + .withSink(buildSink()) .withTtl(100) .build(); final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); assertEquals("UAttributesValidator.Request", validator.toString()); - final UStatus status = validator.validate(attributes); + final ValidationResult status = validator.validate(attributes); assertTrue(status.isSuccess()); - assertEquals("ok", status.msg()); + assertEquals("", status.getMessage()); } @Test @@ -920,10 +871,9 @@ public void test_validating_request_validator_with_wrong_messagetype() { final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); assertEquals("UAttributesValidator.Request", validator.toString()); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Wrong Attribute Type [PUBLISH],Missing TTL,Missing Sink", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Wrong Attribute Type [PUBLISH],Missing TTL,Missing Sink", status.getMessage()); } @Test @@ -938,10 +888,9 @@ public void test_validating_request_validator_with_wrong_bad_ttl() { final UAttributesValidator validator = UAttributesValidator.Validators.REQUEST.validator(); assertEquals("UAttributesValidator.Request", validator.toString()); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid TTL [-1]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid TTL [-1]", status.getMessage()); } @Test @@ -957,10 +906,9 @@ public void test_validating_response_validator_with_wrong_bad_ttl() { final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); assertEquals("UAttributesValidator.Response", validator.toString()); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Invalid TTL [-1]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Invalid TTL [-1]", status.getMessage()); } @Test @@ -977,10 +925,9 @@ public void test_validating_response_validator_with_bad_reqid() { final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); assertEquals("UAttributesValidator.Response", validator.toString()); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals(String.format("Invalid UUID [%s]", id), status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals(String.format("Invalid UUID [%s]", id), status.getMessage()); } @@ -994,10 +941,9 @@ public void test_validating_publish_validator_with_wrong_messagetype() { final UAttributesValidator validator = UAttributesValidator.Validators.PUBLISH.validator(); assertEquals("UAttributesValidator.Publish", validator.toString()); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Wrong Attribute Type [REQUEST]", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Wrong Attribute Type [REQUEST]", status.getMessage()); } @Test @@ -1009,10 +955,9 @@ public void test_validating_response_validator_with_wrong_messagetype() { final UAttributesValidator validator = UAttributesValidator.Validators.RESPONSE.validator(); assertEquals("UAttributesValidator.Response", validator.toString()); - final UStatus status = validator.validate(attributes); - assertTrue(status.isFailed()); - assertEquals(status.getCode(), Code.INVALID_ARGUMENT.value()); - assertEquals("Wrong Attribute Type [PUBLISH],Missing Sink,Missing correlationId", status.msg()); + final ValidationResult status = validator.validate(attributes); + assertTrue(status.isFailure()); + assertEquals("Wrong Attribute Type [PUBLISH],Missing Sink,Missing correlationId", status.getMessage()); } @@ -1027,7 +972,16 @@ public void test_validating_request_containing_token() { final UAttributesValidator validator = UAttributesValidator.getValidator(attributes); assertEquals("UAttributesValidator.Publish", validator.toString()); - final UStatus status = validator.validate(attributes); - assertEquals(UStatus.ok(), status); + final ValidationResult status = validator.validate(attributes); + assertEquals(ValidationResult.success(), status); + } + + private UUri buildSink() { + return UUri.newBuilder() + .setAuthority(UAuthority.newBuilder().setName("vcu.someVin.veh.ultifi.gm.com")) + .setEntity(UEntity.newBuilder().setName("petapp.ultifi.gm.com").setVersionMajor(1)) + .setResource(UResourceBuilder.forRpcResponse()) + .build(); } + } diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java deleted file mode 100644 index e855ce76..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UAuthorityTest.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import nl.jqno.equalsverifier.EqualsVerifier; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.net.Inet6Address; -import java.net.InetAddress; - -import static org.junit.jupiter.api.Assertions.*; - -class UAuthorityTest { - - @Test - @DisplayName("Make sure the equals and hash code works") - public void testHashCodeEquals() { - EqualsVerifier.forClass(UAuthority.class).usingGetClass().verify(); - } - - @Test - @DisplayName("Make sure the toString works") - public void testToString() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "my_VIN"); - String sRemote = uAuthority.toString(); - String expectedRemote = "UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}"; - assertEquals(expectedRemote, sRemote); - - final InetAddress address = createAddressForMicroDeviceForTest(); - UAuthority microRemote = UAuthority.microRemote(address); - String sMicroRemote = microRemote.toString(); - String expectedMicroRemote = "UAuthority{device='null', domain='null', markedRemote=true, address=localhost/127.0.0.1, markedResolved=false}"; - assertEquals(expectedMicroRemote, sMicroRemote); - - UAuthority resolvedRemote = UAuthority.resolvedRemote("VCU", "MY_VIN", address); - assertEquals("UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=localhost/127.0.0.1, markedResolved=true}", resolvedRemote.toString()); - - UAuthority local = UAuthority.local(); - String sLocal = local.toString(); - String expectedLocal = "UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}"; - assertEquals(expectedLocal, sLocal); - - UAuthority empty = UAuthority.empty(); - assertEquals("UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}", empty.toString()); - - } - - @Test - @DisplayName("Make sure the toString works with case sensitivity") - public void testToString_case_sensitivity() { - UAuthority uAuthority = UAuthority.longRemote("vcU", "my_VIN"); - String sRemote = uAuthority.toString(); - String expectedRemote = "UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}"; - assertEquals(expectedRemote, sRemote); - } - - @Test - @DisplayName("Test create a empty uAuthority") - public void test_create_empty_uAuthority() { - UAuthority uAuthority = UAuthority.empty(); - assertTrue(uAuthority.device().isEmpty()); - assertTrue(uAuthority.domain().isEmpty()); - assertTrue(uAuthority.address().isEmpty()); - assertTrue(uAuthority.isLocal()); - assertFalse(uAuthority.isRemote()); - assertFalse(uAuthority.isMarkedRemote()); - assertTrue(uAuthority.isResolved()); - assertTrue(uAuthority.isEmpty()); - assertTrue(uAuthority.isMicroForm()); - assertTrue(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a local uAuthority") - public void test_create_local_uAuthority() { - UAuthority uAuthority = UAuthority.local(); - assertTrue(uAuthority.device().isEmpty()); - assertTrue(uAuthority.domain().isEmpty()); - assertTrue(uAuthority.address().isEmpty()); - assertTrue(uAuthority.isLocal()); - assertFalse(uAuthority.isRemote()); - assertFalse(uAuthority.isMarkedRemote()); - assertTrue(uAuthority.isResolved()); - assertTrue(uAuthority.isEmpty()); - assertTrue(uAuthority.isMicroForm()); - assertTrue(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote uAuthority that supports long UUris") - public void test_create_remote_uAuthority_that_supports_long_uuri() { - String device = "vcu"; - String domain = "myvin"; - UAuthority uAuthority = UAuthority.longRemote(device, domain); - assertEquals(device, uAuthority.device().orElse("")); - assertEquals(domain, uAuthority.domain().orElse("")); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertTrue(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote uAuthority that supports long UUris null device") - public void test_create_remote_uAuthority_that_supports_long_uuri_null_device() { - String domain = "myvin"; - UAuthority uAuthority = UAuthority.longRemote(null, domain); - assertTrue(uAuthority.device().isEmpty()); - assertEquals(domain, uAuthority.domain().orElse("")); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote uAuthority that supports long UUris missing device") - public void test_create_remote_uAuthority_that_supports_long_uuri_missing_device() { - String device = " "; - String domain = "myvin"; - UAuthority uAuthority = UAuthority.longRemote(device, domain); - assertTrue(uAuthority.device().isEmpty()); - assertEquals(domain, uAuthority.domain().orElse("")); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote uAuthority that supports long UUris null domain") - public void test_create_remote_uAuthority_that_supports_long_uuri_null_domain() { - String device = "vcu"; - UAuthority uAuthority = UAuthority.longRemote(device, null); - assertEquals(device, uAuthority.device().orElse("")); - assertTrue(uAuthority.domain().isEmpty()); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertTrue(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote uAuthority that supports micro UUris") - public void test_create_remote_uAuthority_that_supports_micro_uuri() { - final InetAddress address = createAddressForMicroDeviceForTest(); - UAuthority uAuthority = UAuthority.microRemote(address); - assertTrue(uAuthority.device().isEmpty()); - assertTrue(uAuthority.domain().isEmpty()); - assertEquals(address, uAuthority.address().orElse(null)); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertTrue(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote uAuthority that supports micro UUris with null address") - public void test_create_remote_uAuthority_that_supports_micro_uuri_with_null_address() { - UAuthority uAuthority = UAuthority.microRemote(null); - assertTrue(uAuthority.device().isEmpty()); - assertTrue(uAuthority.domain().isEmpty()); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertTrue(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris") - public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri() { - String device = "vcu"; - String domain = "myvin"; - final InetAddress address = createAddressForMicroDeviceForTest(); - UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, address); - assertEquals(device, uAuthority.device().orElse("")); - assertEquals(domain, uAuthority.domain().orElse("")); - assertEquals(address, uAuthority.address().orElse(null)); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertTrue(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertTrue(uAuthority.isMicroForm()); - assertTrue(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with null device") - public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_null_device() { - String domain = "myvin"; - final InetAddress address = createAddressForMicroDeviceForTest(); - UAuthority uAuthority = UAuthority.resolvedRemote(null, domain, address); - assertTrue(uAuthority.device().isEmpty()); - assertEquals(domain, uAuthority.domain().orElse("")); - assertEquals(address, uAuthority.address().orElse(null)); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertTrue(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with blank device") - public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_blank_device() { - String device = " "; - String domain = "myvin"; - final InetAddress address = createAddressForMicroDeviceForTest(); - UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, address); - assertTrue(uAuthority.device().isEmpty()); - assertEquals(domain, uAuthority.domain().orElse("")); - assertEquals(address, uAuthority.address().orElse(null)); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertTrue(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with missing address") - public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_missing_address() { - String device = "vcu"; - String domain = "myvin"; - UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, null); - assertEquals(device, uAuthority.device().orElse("")); - assertEquals(domain, uAuthority.domain().orElse("")); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertFalse(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertTrue(uAuthority.isLongForm()); - } - - @Test - @DisplayName("Test create a remote resolved uAuthority that supports both long and micro UUris with missing data") - public void test_create_remote_resolved_uAuthority_that_supports_long_and_micro_uuri_missing_all_data() { - String device = ""; - String domain = ""; - UAuthority uAuthority = UAuthority.resolvedRemote(device, domain, null); - assertTrue(uAuthority.device().isEmpty()); - assertTrue(uAuthority.domain().isEmpty()); - assertTrue(uAuthority.address().isEmpty()); - assertFalse(uAuthority.isLocal()); - assertTrue(uAuthority.isRemote()); - assertTrue(uAuthority.isMarkedRemote()); - assertFalse(uAuthority.isResolved()); - assertTrue(uAuthority.isEmpty()); - assertFalse(uAuthority.isMicroForm()); - assertFalse(uAuthority.isLongForm()); - } - - private InetAddress createAddressForMicroDeviceForTest() { - return Inet6Address.getLoopbackAddress(); - } - -} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java deleted file mode 100644 index 7231cf63..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UEntityTest.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import nl.jqno.equalsverifier.EqualsVerifier; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - - -class UEntityTest { - - @Test - @DisplayName("Make sure the equals and hash code works") - public void testHashCodeEquals() { - EqualsVerifier.forClass(UEntity.class).usingGetClass().verify(); - } - - @Test - @DisplayName("Make sure the toString works") - public void testToString() { - UEntity use = UEntity.longFormat("body.access", 1); - assertEquals("body.access", use.name()); - assertTrue(use.version().isPresent()); - assertEquals(1, use.version().get()); - - String expected = "UEntity{name='body.access', version=1, id=null, markedResolved=false}"; - assertEquals(expected, use.toString()); - - UEntity use1 = UEntity.longFormat("body.access"); - assertEquals("UEntity{name='body.access', version=null, id=null, markedResolved=false}", use1.toString()); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with name") - public void test_create_use_for_use_with_long_format_uuri_with_name() { - UEntity use = UEntity.longFormat("body.access"); - assertEquals("body.access", use.name()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertTrue(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with name that is blank") - public void test_create_use_for_use_with_long_format_uuri_with_name_that_is_blank() { - UEntity use = UEntity.longFormat(" "); - assertEquals(" ", use.name()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertTrue(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with name that is null, expect exception") - public void test_create_use_for_use_with_long_format_uuri_with_name_that_is_null() { - Exception exception = assertThrows(NullPointerException.class, () -> UEntity.longFormat(null)); - assertTrue(exception.getMessage().contains(" Software Entity must have a name")); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with name and version") - public void test_create_use_for_use_with_long_format_uuri_with_name_and_version() { - UEntity use = UEntity.longFormat("body.access", 1); - assertEquals("body.access", use.name()); - assertEquals(1, use.version().orElse(-1)); - assertTrue(use.id().isEmpty()); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertTrue(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with blank name and null version") - public void test_create_use_for_use_with_long_format_uuri_with_blank_name_and_no_version() { - UEntity use = UEntity.longFormat("", null); - assertEquals("", use.name()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertTrue(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with blank name and null version") - public void test_create_use_for_use_with_long_format_uuri_with_name_and_no_version() { - UEntity use = UEntity.longFormat("body.access", null); - assertEquals("body.access", use.name()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertTrue(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in long format UUri with name and version, null name, expect exception") - public void test_create_use_for_use_with_long_format_uuri_with_name_and_version_null_name() { - Exception exception = assertThrows(NullPointerException.class, () -> UEntity.longFormat(null, 1)); - assertTrue(exception.getMessage().contains(" Software Entity must have a name")); - } - - @Test - @DisplayName("Test creating an empty USE using the empty static method") - public void test_create_empty_using_empty() { - UEntity use = UEntity.empty(); - assertTrue(use.name().isEmpty()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertTrue(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in micro format UUri with id") - public void test_create_use_for_use_with_micro_format_uuri_with_id() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.microFormat(id); - assertTrue(use.name().isBlank()); - assertTrue(use.version().isEmpty()); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in micro format UUri with null id") - public void test_create_use_for_use_with_micro_format_uuri_with_null_id() { - UEntity use = UEntity.microFormat(null); - assertTrue(use.name().isBlank()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertTrue(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in micro format UUri with id and version") - public void test_create_use_for_use_with_micro_format_uuri_with_id_and_version() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.microFormat(id, 1); - assertTrue(use.name().isBlank()); - assertEquals(1, use.version().orElse(-1)); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in micro format UUri with id and null version") - public void test_create_use_for_use_with_micro_format_uuri_with_id_and_null_version() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.microFormat(id, null); - assertTrue(use.name().isBlank()); - assertTrue(use.version().isEmpty()); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a software entity for use in micro format UUri with null id and version") - public void test_create_use_for_use_with_micro_format_uuri_with_null_id_and_version() { - UEntity use = UEntity.microFormat(null, 1); - assertTrue(use.name().isBlank()); - assertEquals(1, use.version().orElse(-1)); - assertTrue(use.id().isEmpty()); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri") - public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.resolvedFormat("body.access", 1, id); - assertEquals("body.access", use.name()); - assertEquals(1, use.version().orElse(-1)); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertTrue(use.isResolved()); - assertTrue(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when name is empty") - public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_when_name_is_empty() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.resolvedFormat(" ", 1, id); - assertEquals("", use.name()); - assertEquals(1, use.version().orElse(-1)); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when name is null") - public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_when_name_is_null() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.resolvedFormat(null, 1, id); - assertEquals("", use.name()); - assertEquals(1, use.version().orElse(-1)); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri with missing version") - public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_version_is_missing() { - Short id = 42; - Short defaultNotUsed = 0; - UEntity use = UEntity.resolvedFormat("body.access", null, id); - assertEquals("body.access", use.name()); - assertTrue(use.version().isEmpty()); - assertEquals(id, use.id().orElse(defaultNotUsed)); - assertFalse(use.isEmpty()); - assertTrue(use.isResolved()); - assertTrue(use.isLongForm()); - assertTrue(use.isMicroForm()); - } - - @Test - @DisplayName("Test creating a resolved software entity for use in long format and micro format UUri when all elements are empty") - public void test_create_resolved_use_for_use_with_long_format_uuri_and_micro_format_uuri_all_empty_elements() { - UEntity use = UEntity.resolvedFormat(" ", null, null); - assertEquals("", use.name()); - assertTrue(use.version().isEmpty()); - assertTrue(use.id().isEmpty()); - assertTrue(use.isEmpty()); - assertFalse(use.isResolved()); - assertFalse(use.isLongForm()); - assertFalse(use.isMicroForm()); - } - -} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java deleted file mode 100644 index c8c45ed4..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UResourceTest.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import nl.jqno.equalsverifier.EqualsVerifier; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class UResourceTest { - - @Test - @DisplayName("Make sure the equals and hash code works") - public void testHashCodeEquals() { - EqualsVerifier.forClass(UResource.class).usingGetClass().verify(); - } - - @Test - @DisplayName("Make sure the toString works") - public void testToString() { - UResource uResource = UResource.longFormat("door", "front_left", "Door"); - String expected = "UResource{name='door', instance='front_left', message='Door', id=null, markedResolved=false}"; - assertEquals(expected, uResource.toString()); - assertFalse(uResource.isEmpty()); - } - - @Test - @DisplayName("Test creating a empty Resource") - public void test_create_empty_Resource() { - UResource uResource = UResource.empty(); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a empty Resource") - public void test_create_empty_Resource2() { - UResource uResource = UResource.longFormat(" ", null, null); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri") - public void test_create_Resource_long_format_uuri() { - UResource uResource = UResource.longFormat("door", "front_left", "Door"); - assertEquals("door", uResource.name()); - assertEquals("front_left", uResource.instance().orElse("")); - assertEquals("Door", uResource.message().orElse("")); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri null instance") - public void test_create_Resource_long_format_uuri_null_instance() { - UResource uResource = UResource.longFormat("door", null, "Door"); - assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertEquals("Door", uResource.message().orElse("")); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri null message") - public void test_create_Resource_long_format_uuri_null_message() { - UResource uResource = UResource.longFormat("door", "front_left", null); - assertEquals("door", uResource.name()); - assertEquals("front_left", uResource.instance().orElse("")); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri all values empty") - public void test_create_Resource_long_format_uuri_all_empty_values() { - UResource uResource = UResource.longFormat(null, " ", " "); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri blank instance and blank message") - public void test_create_Resource_long_format_uuri_all_empty_values_blank_instance_and_message() { - UResource uResource = UResource.longFormat(" ", " ", " "); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri only name") - public void test_create_Resource_long_format_uuri_only_name() { - UResource uResource = UResource.longFormat("door"); - assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri only name but null") - public void test_create_Resource_long_format_uuri_only_name_when_null() { - UResource uResource = UResource.longFormat(null); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in long formatted UUri only name but blank") - public void test_create_Resource_long_format_uuri_only_name_when_blank() { - UResource uResource = UResource.longFormat(" "); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in micro formatted UUri") - public void test_create_Resource_micro_format_uuri() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.microFormat(id); - assertTrue(uResource.name().isEmpty()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a Resource to be used in micro formatted UUri id is null") - public void test_create_Resource_micro_format_uuri_id_is_null() { - UResource uResource = UResource.microFormat(null); - assertTrue(uResource.name().isEmpty()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri") - public void test_create_resolved_Resource_long_and_micro_format_uuri() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", id); - assertEquals("door", uResource.name()); - assertEquals("front_left", uResource.instance().orElse("")); - assertEquals("Door", uResource.message().orElse("")); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertTrue(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty name") - public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_name() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.resolvedFormat(" ", "front_left", "Door", id); - assertTrue(uResource.name().isBlank()); - assertEquals("front_left", uResource.instance().orElse("")); - assertEquals("Door", uResource.message().orElse("")); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty instance") - public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_instance() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.resolvedFormat("door", null, "Door", id); - assertEquals("door", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertEquals("Door", uResource.message().orElse("")); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertTrue(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty id") - public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_id() { - UResource uResource = UResource.resolvedFormat("door", "front_left", "Door", null); - assertEquals("door", uResource.name()); - assertEquals("front_left", uResource.instance().orElse("")); - assertEquals("Door", uResource.message().orElse("")); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating a fully resolved Resource to be used in long and micro formatted UUri empty all") - public void test_create_resolved_Resource_long_and_micro_format_uuri_empty_all() { - UResource uResource = UResource.resolvedFormat(null, " ", " ", null); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating rpc request for long formatted UUri") - public void test_create_rpc_request_long_format() { - UResource uResource = UResource.forRpcRequest("ExecuteDoorCommand"); - assertEquals("rpc", uResource.name()); - assertEquals("ExecuteDoorCommand", uResource.instance().orElse("")); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertTrue(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating rpc request for long formatted UUri empty command name") - public void test_create_rpc_request_long_format_empty_command_Name() { - UResource uResource = UResource.forRpcRequest(" "); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating rpc request for long formatted UUri null command name") - public void test_create_rpc_request_long_format_null_command_Name() { - String commandName = null; - UResource uResource = UResource.forRpcRequest(commandName); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating rpc request for micro formatted UUri") - public void test_create_rpc_request_micro_format() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.forRpcRequest(id); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertTrue(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating rpc request for micro formatted UUri null id") - public void test_create_rpc_request_micro_format_null_id() { - Short id = null; - UResource uResource = UResource.forRpcRequest(id); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating resolved rpc request for long and micro formatted UUri") - public void test_create_resolved_rpc_request_long_and_micro_format() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.forRpcRequest("ExecuteDoorCommand", id); - assertEquals("rpc", uResource.name()); - assertEquals("ExecuteDoorCommand", uResource.instance().orElse("")); - assertTrue(uResource.message().isEmpty()); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertTrue(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertTrue(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating resolved rpc request for long and micro formatted UUri id is null") - public void test_create_resolved_rpc_request_long_and_micro_format_id_null() { - Short id = null; - UResource uResource = UResource.forRpcRequest("ExecuteDoorCommand", id); - assertEquals("rpc", uResource.name()); - assertEquals("ExecuteDoorCommand", uResource.instance().orElse("")); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertTrue(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating resolved rpc request for long and micro formatted UUri null method name") - public void test_create_resolved_rpc_request_long_and_micro_format_null_method_name() { - Short id = 42; - Short notused = 0; - UResource uResource = UResource.forRpcRequest(" ", id); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertTrue(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating resolved rpc request for long and micro formatted UUri missing values") - public void test_create_resolved_rpc_request_long_and_micro_format_missing_values() { - UResource uResource = UResource.forRpcRequest(null, null); - assertEquals("rpc", uResource.name()); - assertTrue(uResource.instance().isEmpty()); - assertTrue(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertTrue(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating rpc response") - public void test_create_rpc_response() { - Short id = 0; - Short notused = 42; - UResource uResource = UResource.forRpcResponse(); - assertEquals("rpc", uResource.name()); - assertEquals("response", uResource.instance().orElse("")); - assertTrue(uResource.message().isEmpty()); - assertEquals(id, uResource.id().orElse(notused)); - assertFalse(uResource.isEmpty()); - assertTrue(uResource.isResolved()); - assertTrue(uResource.isLongForm()); - assertTrue(uResource.isMicroForm()); - assertTrue(uResource.isRPCMethod()); - } - - @Test - @DisplayName("Test creating invalid uResource with only the message") - public void test_create_invalid_uresource_with_only_message() { - UResource uResource = UResource.resolvedFormat("", null, "Door", null); - assertTrue(uResource.name().isBlank()); - assertTrue(uResource.instance().isEmpty()); - assertFalse(uResource.message().isEmpty()); - assertTrue(uResource.id().isEmpty()); - assertFalse(uResource.isEmpty()); - assertFalse(uResource.isResolved()); - assertFalse(uResource.isLongForm()); - assertFalse(uResource.isMicroForm()); - assertFalse(uResource.isRPCMethod()); - } -} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java b/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java deleted file mode 100644 index 784f23e5..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/datamodel/UUriTest.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.datamodel; - -import nl.jqno.equalsverifier.EqualsVerifier; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -class UUriTest { - - @Test - @DisplayName("Make sure the equals and hash code works") - public void testHashCodeEquals() { - EqualsVerifier.forClass(UUri.class).usingGetClass().verify(); - } - - @Test - @DisplayName("Make sure the toString works") - public void testToString() { - UAuthority uAuthorityLocal = UAuthority.local(); - UAuthority uAuthorityRemote = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = UEntity.longFormat("body.access", 1); - UResource uResource = UResource.longFormat("door", "front_left", null); - - UUri uri = new UUri(uAuthorityLocal, use, uResource); - - String expected = "UriPart{uAuthority=UAuthority{device='null', domain='null', markedRemote=false, address=null, markedResolved=true}, " + - "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + - "uResource=UResource{name='door', instance='front_left', message='null', id=null, markedResolved=false}}"; - assertEquals(expected, uri.toString()); - - UUri uriRemote = new UUri(uAuthorityRemote, use, uResource); - String expectedRemote = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}, " + - "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + - "uResource=UResource{name='door', instance='front_left', message='null', id=null, markedResolved=false}}"; - assertEquals(expectedRemote, uriRemote.toString()); - - UUri uri2 = new UUri(uAuthorityRemote, use, UResource.empty()); - String expectedUri2 = "UriPart{uAuthority=UAuthority{device='vcu', domain='my_vin', markedRemote=true, address=null, markedResolved=false}, " + - "uEntity=UEntity{name='body.access', version=1, id=null, markedResolved=false}, " + - "uResource=UResource{name='', instance='null', message='null', id=null, markedResolved=false}}"; - assertEquals(expectedUri2, uri2.toString()); - } - - @Test - @DisplayName("Test creating full local uri") - public void test_create_full_local_uri() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.longFormat("body.access"); - UResource uResource = UResource.longFormat("door", "front_left", null); - - UUri uri = new UUri(uAuthority, use, uResource); - - assertEquals(uAuthority, uri.uAuthority()); - assertEquals(use, uri.uEntity()); - assertEquals(uResource, uri.uResource()); - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test creating full long uri") - public void test_create_full_long_remote_uri() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = UEntity.longFormat("body.access", 1); - UResource uResource = UResource.longFormat("door", "front_left", "Door"); - - UUri uri = new UUri(uAuthority, use, uResource); - - assertEquals(uAuthority, uri.uAuthority()); - assertEquals(use, uri.uEntity()); - assertEquals(uResource, uri.uResource()); - - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test creating rpc response uri") - public void test_create_rpc_response_uri() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = UEntity.longFormat("body.access", 1); - - UUri uri = UUri.rpcResponse(uAuthority, use); - - assertEquals(uAuthority, uri.uAuthority()); - assertEquals(use, uri.uEntity()); - assertTrue(uri.uResource().isRPCMethod()); - - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - - @Test - @DisplayName("Test creating full uri with resource but no message using the constructor") - public void test_create_uri_no_message_with_constructor() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = UEntity.longFormat("body.access", 1); - UResource uResource = UResource.longFormat("door"); - - UUri uri = new UUri(uAuthority, use, "door"); - - assertEquals(uAuthority, uri.uAuthority()); - assertEquals(use, uri.uEntity()); - assertEquals(uResource, uri.uResource()); - - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test creating a uri with a null authority, expect creation with an empty authority") - public void test_create_uri_null_authority() { - UEntity use = UEntity.longFormat("body.access", 1); - UResource uResource = UResource.longFormat("door", "front_left", null); - - UUri uri = new UUri(null, use, uResource); - assertEquals(UAuthority.empty(), uri.uAuthority()); - - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test creating a uri with a null software entity, expect creation with an empty software entity") - public void test_create_uri_null_use() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UResource uResource = UResource.longFormat("door", "front_left", null); - - UUri uri = new UUri(uAuthority, null, uResource); - assertEquals(UEntity.empty(), uri.uEntity()); - - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test creating a uri with a null ulitfi resource, expect creation with an empty resource") - public void test_create_uri_null_uResource() { - UAuthority uAuthority = UAuthority.longRemote("VCU", "MY_VIN"); - UEntity use = UEntity.longFormat("body.access", 1); - UResource uResource = UResource.empty(); - - UUri uri = new UUri(uAuthority, use, uResource); - assertEquals(UResource.empty(), uri.uResource()); - - assertFalse(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test creating an empty uri using the empty static method") - public void test_create_empty_using_empty() { - UUri uri = UUri.empty(); - - assertTrue(uri.uAuthority().isLocal()); - assertTrue(uri.uEntity().isEmpty()); - assertTrue(uri.uResource().isEmpty()); - - assertTrue(uri.isEmpty()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test isResolved and isLongForm for valid URIs") - public void test_isResolved_and_isLongForm() throws UnknownHostException { - UUri uri = UUri.empty(); - - assertFalse(uri.isResolved()); - assertTrue(uri.isLongForm()); - assertFalse(uri.isMicroForm()); - - UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); - assertFalse(uri2.isResolved()); - assertTrue(uri2.isLongForm()); - assertFalse(uri2.isMicroForm()); - - UUri uri3 = new UUri(UAuthority.local(), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertFalse(uri3.isResolved()); - assertTrue(uri3.isLongForm()); - assertFalse(uri3.isMicroForm()); - - UUri uri4 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertTrue(uri4.isResolved()); - assertTrue(uri4.isLongForm()); - assertFalse(uri3.isMicroForm()); - - UUri uri11 = new UUri(UAuthority.local(), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.forRpcRequest("Raise")); - assertFalse(uri11.isResolved()); - assertTrue(uri11.isLongForm()); - assertFalse(uri11.isMicroForm()); - - UUri uri5 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); - assertFalse(uri5.isResolved()); - assertTrue(uri5.isLongForm()); - assertFalse(uri5.isMicroForm()); - - UUri uri6 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertFalse(uri6.isResolved()); - assertTrue(uri6.isLongForm()); - assertFalse(uri6.isMicroForm()); - - UUri uri7 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertFalse(uri7.isResolved()); - assertTrue(uri7.isLongForm()); - assertFalse(uri7.isMicroForm()); - - UUri uri14 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.resolvedFormat("Hartley", 1, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertFalse(uri14.isResolved()); - assertTrue(uri14.isLongForm()); - assertFalse(uri14.isMicroForm()); - - - UUri uri8 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.forRpcRequest("Raise")); - assertFalse(uri8.isResolved()); - assertTrue(uri8.isLongForm()); - assertFalse(uri8.isMicroForm()); - - UUri uri9 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.longFormat("Hartley"), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertFalse(uri9.isResolved()); - assertTrue(uri9.isLongForm()); - assertFalse(uri9.isMicroForm()); - - UUri uri10 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertTrue(uri10.isResolved()); - assertTrue(uri10.isLongForm()); - assertTrue(uri10.isMicroForm()); - - UUri uri12 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.microFormat((short)2)); - assertFalse(uri12.isResolved()); - assertFalse(uri12.isLongForm()); - assertTrue(uri12.isMicroForm()); - - UUri uri19 = new UUri(UAuthority.microRemote(InetAddress.getByName("192.168.1.100")), UEntity.resolvedFormat("Hartley", null, (short)2), UResource.microFormat((short)2)); - assertFalse(uri19.isResolved()); - assertFalse(uri19.isLongForm()); - assertTrue(uri19.isMicroForm()); - - UUri uri16 = new UUri(UAuthority.local(), UEntity.microFormat((short)2, 1), UResource.microFormat((short)2)); - assertFalse(uri16.isResolved()); - assertFalse(uri16.isLongForm()); - assertTrue(uri16.isMicroForm()); - - - UUri uri17 = new UUri(UAuthority.resolvedRemote("vcu", "vin", InetAddress.getByName("192.168.1.100")), UEntity.microFormat((short)2, 1), UResource.resolvedFormat("Raise", "Salary", "Bonus", (short)1)); - assertFalse(uri17.isResolved()); - assertFalse(uri17.isLongForm()); - assertTrue(uri17.isMicroForm()); - - UUri uri18 = new UUri(UAuthority.local(), UEntity.microFormat((short)2, 1), UResource.microFormat((short)2)); - assertFalse(uri18.isResolved()); - assertFalse(uri18.isLongForm()); - assertTrue(uri18.isMicroForm()); - - } - -} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java index 89bd73c1..2d49db12 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.java @@ -20,32 +20,30 @@ */ package org.eclipse.uprotocol.uri.serializer; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import org.eclipse.uprotocol.uri.builder.UResourceBuilder; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Optional; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; public class LongUriSerializerTest { @Test @DisplayName("Test using the serializers") public void test_using_the_serializers() { - final UUri uri = new UUri(UAuthority.local(), UEntity.longFormat("hartley"), UResource.forRpcRequest("raise")); + final UUri uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("hartley")) + .setResource(UResourceBuilder.forRpcRequest("raise")) + .build(); final String strUri = LongUriSerializer.instance().serialize(uri); assertEquals("/hartley//rpc.raise", strUri); final UUri uri2 = LongUriSerializer.instance().deserialize(strUri); assertEquals(uri, uri2); } - +/* @Test @DisplayName("Test parse uProtocol uri that is null") public void test_parse_protocol_uri_when_is_null() { @@ -71,8 +69,8 @@ public void test_parse_protocol_uri_when_is_empty_string() { public void test_parse_protocol_uri_with_schema_and_slash() { String uri = "/"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); assertTrue(Uri.isEmpty()); String uri2 = LongUriSerializer.instance().serialize(UUri.empty()); @@ -84,8 +82,8 @@ public void test_parse_protocol_uri_with_schema_and_slash() { public void test_parse_protocol_uri_with_schema_and_double_slash() { String uri = "//"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertFalse(Uri.uAuthority().isLocal()); - assertTrue(Uri.uAuthority().isMarkedRemote()); + assertFalse(Uri.getAuthority().isLocal()); + assertTrue(!Uri.getAuthority().getLocal()); assertTrue(Uri.isEmpty()); } @@ -94,11 +92,11 @@ public void test_parse_protocol_uri_with_schema_and_double_slash() { public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { String uri = "///body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertFalse(Uri.uAuthority().isLocal()); - assertTrue(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertFalse(Uri.getAuthority().isLocal()); + assertTrue(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -106,11 +104,11 @@ public void test_parse_protocol_uri_with_schema_and_3_slash_and_something() { public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { String uri = "////body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertFalse(Uri.uAuthority().isLocal()); - assertTrue(Uri.uAuthority().isMarkedRemote()); - assertTrue(Uri.uEntity().name().isBlank()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertFalse(Uri.getAuthority().isLocal()); + assertTrue(!Uri.getAuthority().getLocal()); + assertTrue(Uri.getEntity().getName().isBlank()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -118,12 +116,12 @@ public void test_parse_protocol_uri_with_schema_and_4_slash_and_something() { public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { String uri = "/////body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertFalse(Uri.uAuthority().isLocal()); - assertTrue(Uri.uAuthority().isMarkedRemote()); - assertTrue(Uri.uEntity().isEmpty()); - assertEquals("body", Uri.uResource().name()); - assertEquals("access", Uri.uResource().instance().orElse("")); - assertTrue(Uri.uResource().message().isEmpty()); + assertFalse(Uri.getAuthority().isLocal()); + assertTrue(!Uri.getAuthority().getLocal()); + assertTrue(Uri.getEntity().isEmpty()); + assertEquals("body", Uri.getResource().getName()); + assertEquals("access", Uri.getResource().instance().orElse("")); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -131,8 +129,8 @@ public void test_parse_protocol_uri_with_schema_and_5_slash_and_something() { public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { String uri = "//////body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertFalse(Uri.uAuthority().isLocal()); - assertTrue(Uri.uAuthority().isMarkedRemote()); + assertFalse(Uri.getAuthority().isLocal()); + assertTrue(!Uri.getAuthority().getLocal()); assertTrue(Uri.isEmpty()); } @@ -141,11 +139,11 @@ public void test_parse_protocol_uri_with_schema_and_6_slash_and_something() { public void test_parse_protocol_uri_with_local_service_no_version() { String uri = "/body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -153,11 +151,11 @@ public void test_parse_protocol_uri_with_local_service_no_version() { public void test_parse_protocol_uri_with_local_service_with_version() { String uri = "/body.access/1"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertEquals(1, Uri.uEntity().version().orElse(10)); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertEquals(1, Uri.getEntity().version().orElse(10)); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -165,13 +163,13 @@ public void test_parse_protocol_uri_with_local_service_with_version() { public void test_parse_protocol_uri_with_local_service_no_version_with_resource_name_only() { String uri = "/body.access//door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isEmpty()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isEmpty()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -179,13 +177,13 @@ public void test_parse_protocol_uri_with_local_service_no_version_with_resource_ public void test_parse_protocol_uri_with_local_service_with_version_with_resource_name_only() { String uri = "/body.access/1/door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertEquals(1, Uri.uEntity().version().orElse(10)); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isEmpty()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertEquals(1, Uri.getEntity().version().orElse(10)); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isEmpty()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -193,63 +191,63 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance() { String uri = "/body.access//door.front_left"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @DisplayName("Test parse uProtocol uri with local service with version with resource and instance only") - public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_message() { + public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_getMessage() { String uri = "/body.access/1/door.front_left"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @DisplayName("Test parse uProtocol uri with local service no version with resource with instance and message") - public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance_and_message() { + public void test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance_and_getMessage() { String uri = "/body.access//door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @DisplayName("Test parse uProtocol uri with local service with version with resource with instance and message") - public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_instance_and_message() { + public void test_parse_protocol_uri_with_local_service_with_version_with_resource_with_instance_and_getMessage() { String uri = "/body.access/1/door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @@ -257,14 +255,14 @@ public void test_parse_protocol_uri_with_local_service_with_version_with_resourc public void test_parse_protocol_rpc_uri_with_local_service_no_version() { String uri = "/petapp//rpc.response"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("petapp", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("rpc", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("response", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("petapp", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("rpc", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("response", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -272,15 +270,15 @@ public void test_parse_protocol_rpc_uri_with_local_service_no_version() { public void test_parse_protocol_rpc_uri_with_local_service_with_version() { String uri = "/petapp/1/rpc.response"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("petapp", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("rpc", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("response", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("petapp", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("rpc", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("response", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -288,12 +286,12 @@ public void test_parse_protocol_rpc_uri_with_local_service_with_version() { public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() { String uri = "//VCU"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isEmpty()); - assertTrue(Uri.uEntity().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isEmpty()); + assertTrue(Uri.getEntity().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -301,13 +299,13 @@ public void test_parse_protocol_uri_with_remote_service_only_device_no_domain() public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() { String uri = "//VCU.MY_CAR_VIN"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertTrue(Uri.uEntity().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertTrue(Uri.getEntity().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -315,13 +313,13 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_domain() public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_domain() { String uri = "//cloud.uprotocol.example.com"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertTrue(Uri.uEntity().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertTrue(Uri.getEntity().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -329,14 +327,14 @@ public void test_parse_protocol_uri_with_remote_service_only_device_and_cloud_do public void test_parse_protocol_uri_with_remote_service_no_version() { String uri = "//VCU.MY_CAR_VIN/body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -344,14 +342,14 @@ public void test_parse_protocol_uri_with_remote_service_no_version() { public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { String uri = "//cloud.uprotocol.example.com/body.access"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -359,15 +357,15 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version() { public void test_parse_protocol_uri_with_remote_service_with_version() { String uri = "//VCU.MY_CAR_VIN/body.access/1"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -375,15 +373,15 @@ public void test_parse_protocol_uri_with_remote_service_with_version() { public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { String uri = "//cloud.uprotocol.example.com/body.access/1"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertTrue(Uri.uResource().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertTrue(Uri.getResource().isEmpty()); } @Test @@ -391,16 +389,16 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version() { public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access//door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isEmpty()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isEmpty()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -408,16 +406,16 @@ public void test_parse_protocol_uri_with_remote_service_no_version_with_resource public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access//door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isEmpty()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isEmpty()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -425,17 +423,17 @@ public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_re public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_name_only() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isEmpty()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isEmpty()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -443,132 +441,132 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour public void test_parse_protocol_uri_with_remote_service_cloud_with_version_with_resource_name_only() { String uri = "//cloud.uprotocol.example.com/body.access/1/door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isEmpty()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isEmpty()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance no message") - public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_message() { + public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_getMessage() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance no message") - public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_message() { + public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_getMessage() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance and message") - public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_message() { + public void test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_getMessage() { String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource and instance and message") - public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_message() { + public void test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_getMessage() { String uri = "//cloud.uprotocol.example.com/body.access//door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance and message") - public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_message() { + public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_getMessage() { String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("my_car_vin", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("my_car_vin", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource and instance and message") - public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_message() { + public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_getMessage() { String uri = "//cloud.uprotocol.example.com/body.access/1/door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("cloud", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("uprotocol.example.com", Uri.uAuthority().domain().get()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("cloud", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("uprotocol.example.com", Uri.getAuthority().domain().get()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @@ -576,17 +574,17 @@ public void test_parse_protocol_uri_with_remote_cloud_service_with_version_with_ public void test_parse_protocol_uri_with_remote_service_with_version_with_resource_with_message_device_no_domain() { String uri = "//VCU/body.access/1/door.front_left"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("vcu", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isEmpty()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("vcu", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isEmpty()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -594,17 +592,17 @@ public void test_parse_protocol_uri_with_remote_service_with_version_with_resour public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { String uri = "//bo.cloud/petapp//rpc.response"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("bo", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("cloud", Uri.uAuthority().domain().get()); - assertEquals("petapp", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("rpc", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("response", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("bo", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("cloud", Uri.getAuthority().domain().get()); + assertEquals("petapp", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("rpc", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("response", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -612,18 +610,18 @@ public void test_parse_protocol_rpc_uri_with_remote_service_no_version() { public void test_parse_protocol_rpc_uri_with_remote_service_with_version() { String uri = "//bo.cloud/petapp/1/rpc.response"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isRemote()); - assertTrue(Uri.uAuthority().device().isPresent()); - assertEquals("bo", Uri.uAuthority().device().get()); - assertTrue(Uri.uAuthority().domain().isPresent()); - assertEquals("cloud", Uri.uAuthority().domain().get()); - assertEquals("petapp", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isPresent()); - assertEquals(1, Uri.uEntity().version().get()); - assertEquals("rpc", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("response", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isEmpty()); + assertTrue(Uri.getAuthority().isRemote()); + assertTrue(Uri.getAuthority().getName().isPresent()); + assertEquals("bo", Uri.getAuthority().getName().get()); + assertTrue(Uri.getAuthority().domain().isPresent()); + assertEquals("cloud", Uri.getAuthority().domain().get()); + assertEquals("petapp", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isPresent()); + assertEquals(1, Uri.getEntity().version().get()); + assertEquals("rpc", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("response", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isEmpty()); } @Test @@ -688,7 +686,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version with resource with instance no message") - public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_getMessage() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -697,7 +695,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource with instance no message") - public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_getMessage() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -706,7 +704,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version with resource with instance and message") - public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_getMessage() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -715,7 +713,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_serv @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource with instance and message") - public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_getMessage() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.local(), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -778,7 +776,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource with instance no message") - public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_getMessage() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -787,7 +785,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote cloud authority with service and version with resource with instance no message") - public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_getMessage() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("cloud", "uprotocol.example.com"), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -796,7 +794,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authori @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource with instance no message") - public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_getMessage() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", null)); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -805,7 +803,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource with instance and message") - public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_getMessage() { UEntity use = UEntity.longFormat("body.access", 1); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -814,7 +812,7 @@ public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_ser @Test @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource with instance and message") - public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_message() { + public void test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_getMessage() { UEntity use = UEntity.longFormat("body.access"); UUri Uri = new UUri(UAuthority.longRemote("VCU", "MY_CAR_VIN"), use, UResource.longFormat("door", "front_left", "Door")); String uProtocolUri = LongUriSerializer.instance().serialize(Uri); @@ -885,15 +883,15 @@ public void test_custom_scheme_no_scheme() { public void test_parse_local_protocol_uri_with_custom_scheme() { String uri = "custom:/body.access//door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertTrue(Uri.uAuthority().isLocal()); - assertFalse(Uri.uAuthority().isMarkedRemote()); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertTrue(Uri.uResource().instance().isPresent()); - assertEquals("front_left", Uri.uResource().instance().get()); - assertTrue(Uri.uResource().message().isPresent()); - assertEquals("Door", Uri.uResource().message().get()); + assertTrue(Uri.getAuthority().isLocal()); + assertFalse(!Uri.getAuthority().getLocal()); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertTrue(Uri.getResource().instance().isPresent()); + assertEquals("front_left", Uri.getResource().instance().get()); + assertTrue(Uri.getResource().getMessage().isPresent()); + assertEquals("Door", Uri.getResource().getMessage().get()); } @Test @@ -902,15 +900,15 @@ public void test_parse_remote_protocol_uri_with_custom_scheme() { String uri = "custom://vcu.vin/body.access//door.front_left#Door"; String uri2 = "//vcu.vin/body.access//door.front_left#Door"; UUri Uri = LongUriSerializer.instance().deserialize(uri); - assertFalse(Uri.uAuthority().isLocal()); - assertTrue(Uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", Uri.uAuthority().device().orElse("")); - assertEquals("vin", Uri.uAuthority().domain().orElse("")); - assertEquals("body.access", Uri.uEntity().name()); - assertTrue(Uri.uEntity().version().isEmpty()); - assertEquals("door", Uri.uResource().name()); - assertEquals("front_left", Uri.uResource().instance().orElse("")); - assertEquals("Door", Uri.uResource().message().orElse("")); + assertFalse(Uri.getAuthority().isLocal()); + assertTrue(!Uri.getAuthority().getLocal()); + assertEquals("vcu", Uri.getAuthority().getName().orElse("")); + assertEquals("vin", Uri.getAuthority().domain().orElse("")); + assertEquals("body.access", Uri.getEntity().getName()); + assertTrue(Uri.getEntity().version().isEmpty()); + assertEquals("door", Uri.getResource().getName()); + assertEquals("front_left", Uri.getResource().instance().orElse("")); + assertEquals("Door", Uri.getResource().getMessage().orElse("")); assertEquals(uri2, LongUriSerializer.instance().serialize(Uri)); } @@ -1004,4 +1002,5 @@ void test_deserialize_long_and_micro_passing_valid_values() throws UnknownHostEx Optional uri2 = LongUriSerializer.instance().buildResolved(longUUri, microUUri); assertEquals(uri, uri2.orElse(UUri.empty())); } + */ } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java index 1855f705..a56f2cfa 100644 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java +++ b/src/test/java/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.java @@ -23,34 +23,37 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.Arrays; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; +import java.util.Base64; + +import org.eclipse.uprotocol.uri.builder.UResourceBuilder; +import org.eclipse.uprotocol.uri.validator.UriValidator; +import org.eclipse.uprotocol.v1.UAuthority; +import org.eclipse.uprotocol.v1.UEntity; +import org.eclipse.uprotocol.v1.UResource; +import org.eclipse.uprotocol.v1.UUri; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.platform.commons.annotation.Testable; public class MicroUriSerializerTest { - + + @Test @DisplayName("Test serialize and deserialize empty content") public void test_empty() { - UUri uri = UUri.empty(); - byte[] bytes = MicroUriSerializer.instance().serialize(uri); + + byte[] bytes = MicroUriSerializer.instance().serialize(UUri.getDefaultInstance()); assertEquals(bytes.length, 0); UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); - assertTrue(uri2.isEmpty()); + assertTrue(UriValidator.isEmpty(uri2)); } @Test @@ -61,17 +64,18 @@ public void test_null() { assertEquals(bytes.length, 0); UUri uri2 = MicroUriSerializer.instance().deserialize(null); - assertTrue(uri2.isEmpty()); + assertTrue(UriValidator.isEmpty(uri2)); } @Test @DisplayName("Test happy path Byte serialization of local UUri") public void test_serialize_uri() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.microFormat((short)2, 1); - UResource uResource = UResource.microFormat((short)3); + + UUri uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setId(29999).setVersionMajor(254)) + .setResource(UResource.newBuilder().setId(19999)) + .build(); - UUri uri = new UUri(uAuthority, use, uResource); byte[] bytes = MicroUriSerializer.instance().serialize(uri); UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); @@ -79,227 +83,40 @@ public void test_serialize_uri() { assertEquals(uri, uri2); } - - @Test - @DisplayName("Test happy path with null version") - public void test_serialize_uri_without_version() { - UAuthority uAuthority = UAuthority.local(); - UEntity use = UEntity.microFormat((short)2, null); - UResource uResource = UResource.microFormat((short)3); - - UUri uri = new UUri(uAuthority, use, uResource); - - byte[] bytes = MicroUriSerializer.instance().serialize(uri); - UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); - - assertEquals(uri, uri2); - } - @Test @DisplayName("Test Serialize a remote UUri to micro without the address") public void test_serialize_remote_uri_without_address() { - UAuthority uAuthority = UAuthority.longRemote("vcu", "vin"); - UEntity use = UEntity.microFormat((short)2, 1); - UResource uResource = UResource.microFormat((short)3); - - UUri uri = new UUri(uAuthority, use, uResource); + UUri uri = UUri.newBuilder() + .setAuthority(UAuthority.newBuilder().setName("vcu.vin")) + .setEntity(UEntity.newBuilder().setId(29999).setVersionMajor(254)) + .setResource(UResource.newBuilder().setId(19999)) + .build(); byte[] bytes = MicroUriSerializer.instance().serialize(uri); assertTrue(bytes.length == 0); } - - @Test - @DisplayName("Test serialize invalid UUris") - public void test_serialize_invalid_uuris() { - UUri uri = new UUri(UAuthority.local(), UEntity.microFormat((short)1, null), UResource.empty()); - byte[] bytes = MicroUriSerializer.instance().serialize(uri); - assertEquals(bytes.length, 0); - - UUri uri2 = new UUri(UAuthority.local(), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); - byte[] bytes2 = MicroUriSerializer.instance().serialize(uri2); - assertEquals(bytes2.length, 0); - - UUri uri3 = new UUri(UAuthority.longRemote("null", "null"), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); - byte[] bytes3 = MicroUriSerializer.instance().serialize(uri3); - assertEquals(bytes3.length, 0); - - UUri uri4 = new UUri(UAuthority.resolvedRemote("vcu", "vin", null), UEntity.longFormat("", null), UResource.forRpcRequest("", (short)1)); - byte[] bytes4 = MicroUriSerializer.instance().serialize(uri4); - assertEquals(bytes4.length, 0); - } - @Test - @DisplayName("Test serialize and deserialize IPv4 UUris") - public void test_serialize_ipv4_uri() throws UnknownHostException { - UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("192.168.1.100")); - UEntity use = UEntity.microFormat((short)2, 1); - UResource uResource = UResource.microFormat((short)3); - UUri uri = new UUri(uAuthority, use, uResource); + @DisplayName("Test serialize Uri missing uE ID") + public void test_serialize_uri_missing_ids() { + UUri uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("hartley")) + .setResource(UResourceBuilder.forRpcResponse()) + .build(); byte[] bytes = MicroUriSerializer.instance().serialize(uri); - UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); - assertEquals(uri, uri2); + assertTrue(bytes.length == 0); } @Test - @DisplayName("Test serialize and deserialize IPv6 UUris") - public void test_serialize_ipv6_uri() throws UnknownHostException { - UAuthority uAuthority = UAuthority.microRemote(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334")); - UEntity use = UEntity.microFormat((short)2, 1); - UResource uResource = UResource.microFormat((short)3); - UUri uri = new UUri(uAuthority, use, uResource); + @DisplayName("Test serialize Uri missing resource") + public void test_serialize_uri_missing_resource_id() { + UUri uri = UUri.newBuilder() + .setEntity(UEntity.newBuilder().setName("hartley")) + .build(); byte[] bytes = MicroUriSerializer.instance().serialize(uri); - UUri uri2 = MicroUriSerializer.instance().deserialize(bytes); - assertEquals(uri, uri2); - } - - @Test - @DisplayName("Test deserialize with invalid local micro uri") - public void test_deserialize_with_valid_local_uri() { - - byte[] bytes = {0x1, 0x0, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertFalse(uri.isEmpty()); - assertTrue(uri.isMicroForm()); - assertFalse(uri.isResolved()); - assertFalse(uri.isLongForm()); - assertTrue(uri.uAuthority().isLocal()); - assertTrue(uri.uEntity().version().isPresent()); - assertEquals(uri.uEntity().version().get(),(short)1); - assertTrue(uri.uEntity().id().isPresent()); - assertEquals(uri.uEntity().id().get(), (short)2); - assertTrue(uri.uResource().id().isPresent()); - assertEquals(uri.uResource().id().get(), (short)5); - } - - @Test - @DisplayName("Test deserialize with valid IPv4 micro uri") - public void test_deserialize_with_valid_ipv4_uri() { - - byte[] bytes = {0x1, 0x1, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0, (byte)192, (byte)168, 1, (byte)100}; - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertFalse(uri.isEmpty()); - assertTrue(uri.isMicroForm()); - assertFalse(uri.isResolved()); - assertFalse(uri.isLongForm()); - assertTrue(uri.uAuthority().isRemote()); - assertTrue(uri.uEntity().version().isPresent()); - assertEquals(uri.uEntity().version().get(),(short)1); - assertTrue(uri.uEntity().id().isPresent()); - assertEquals(uri.uEntity().id().get(), (short)2); - assertTrue(uri.uResource().id().isPresent()); - assertEquals(uri.uResource().id().get(), (short)5); - assertTrue(uri.uAuthority().address().isPresent()); - try { - assertEquals(uri.uAuthority().address().get(), Inet4Address.getByName("192.168.1.100")); - } catch (UnknownHostException e) { - assertTrue(false); - } - } - - @Test - @DisplayName("Test deserialize with valid IPv6 micro uri") - public void test_deserialize_with_valid_ipv6_uri() { - try { - InetAddress ipv6 = InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"); - byte[] ipv6Bytes = ipv6.getAddress(); - - byte[] header = {0x1, 0x2, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - outputStream.write(header); - outputStream.write(ipv6Bytes); - - byte[] bytes = outputStream.toByteArray(); - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertFalse(uri.isEmpty()); - assertTrue(uri.isMicroForm()); - assertFalse(uri.isResolved()); - assertFalse(uri.isLongForm()); - assertTrue(uri.uAuthority().isRemote()); - assertTrue(uri.uEntity().version().isPresent()); - assertEquals(uri.uEntity().version().get(),(short)1); - assertTrue(uri.uEntity().id().isPresent()); - assertEquals(uri.uEntity().id().get(), (short)2); - assertTrue(uri.uResource().id().isPresent()); - assertEquals(uri.uResource().id().get(), (short)5); - assertTrue(uri.uAuthority().address().isPresent()); - assertEquals(uri.uAuthority().address().get(), ipv6); - } catch (Exception e) { - assertTrue(false); - } - } - - @Test - @DisplayName("Test deserialize with invalid version") - public void test_deserialize_with_invalid_version() { - byte[] bytes = {0x9, 0x0, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertTrue(uri.isEmpty()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test deserialize with invalid type") - public void test_deserialize_with_invalid_type() { - byte[] bytes = {0x1, 0x9, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertTrue(uri.isEmpty()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test deserialize with wrong size for local micro URI") - public void test_deserialize_with_wrong_size_for_local_micro_uri() { - byte[] bytes = {0x1, 0x0, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0, 0x0}; - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertTrue(uri.isEmpty()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test deserialize with wrong size for IPv4 micro URI") - public void test_deserialize_with_wrong_size_for_ipv4_micro_uri() { - byte[] bytes = {0x1, 0x1, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0, 0x0, (byte)192, (byte)168, 1, (byte)100}; - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertTrue(uri.isEmpty()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } - - @Test - @DisplayName("Test deserialize with wrong size for IPv6 micro URI") - public void test_deserialize_with_wrong_size_for_ipv6_micro_uri() { - try { - byte[] ipv6Bytes = new byte[30]; - - byte[] header = {0x1, 0x2, 0x0, 0x5, 0x0, 0x2, 0x1, 0x0}; - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - outputStream.write(header); - outputStream.write(ipv6Bytes); - - byte[] bytes = outputStream.toByteArray(); - - UUri uri = MicroUriSerializer.instance().deserialize(bytes); - assertTrue(uri.isEmpty()); - assertFalse(uri.isMicroForm()); - assertFalse(uri.isResolved()); - } catch (Exception e) { - assertTrue(false); - } + assertTrue(bytes.length == 0); } - + } diff --git a/src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java b/src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java deleted file mode 100644 index 921ac106..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ -package org.eclipse.uprotocol.uri.serializer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -public class ShortUriSerializerTest { - @Test - @DisplayName("Test serialize empty UUri") - public void test_serialize_empty_uuri() { - final String strUri = ShortUriSerializer.instance().serialize(UUri.empty()); - assertEquals("", strUri); - } - - @Test - @DisplayName("Test serialize null UUri") - public void test_serialize_null_uuri() { - final String strUri = ShortUriSerializer.instance().serialize(null); - assertEquals("", strUri); - } - - @Test - @DisplayName("Test serialize Resolved local UUri") - public void test_serialize_resolved_local_uuri() { - final UEntity uEntity = UEntity.resolvedFormat("hartley", 1, (short)2); - final UResource uResource = UResource.resolvedFormat("salary", "raise", "Salary", (short)4); - final UUri uri = new UUri(UAuthority.local(), uEntity, uResource); - final String strUri = ShortUriSerializer.instance().serialize(uri); - assertFalse(strUri.isEmpty()); - assertEquals("s:/2/1/4", strUri); - } - - @Test - @DisplayName("Test serialize Resolved remote UUri") - public void test_serialize_resolved_remote_uuri() { - final UAuthority uAuthority = UAuthority.longRemote("vcu", "vin"); - final UEntity uEntity = UEntity.resolvedFormat("hartley", 1, (short)2); - final UResource uResource = UResource.resolvedFormat("salary", "raise", "Salary", (short)4); - final UUri uri = new UUri(uAuthority, uEntity, uResource); - final String strUri = ShortUriSerializer.instance().serialize(uri); - assertFalse(strUri.isEmpty()); - assertEquals("s://vcu.vin/2/1/4", strUri); - } - - @Test - @DisplayName("Test serialize with empty authority names") - public void test_serialize_missing_authority_names() { - final UAuthority uAuthority = UAuthority.longRemote("", ""); - final UEntity uEntity = UEntity.microFormat((short)2, 1); - final UResource uResource = UResource.microFormat((short)4); - final UUri uri = new UUri(uAuthority, uEntity, uResource); - final String strUri = ShortUriSerializer.instance().serialize(uri); - assertEquals("s:///2/1/4", strUri); - } - - @Test - @DisplayName("Test serialize with empty UEntity") - public void test_serialize_empty_uentity() { - final UAuthority uAuthority = UAuthority.local(); - final UEntity uEntity = UEntity.empty(); - final UResource uResource = UResource.microFormat((short)4); - final UUri uri = new UUri(uAuthority, uEntity, uResource); - final String strUri = ShortUriSerializer.instance().serialize(uri); - assertEquals("s:/", strUri); - } - - @Test - @DisplayName("Test serialize with empty UResource") - public void test_serialize_empty_uresource() { - final UAuthority uAuthority = UAuthority.local(); - final UEntity uEntity = UEntity.microFormat((short)2, 1); - final UResource uResource = UResource.empty(); - final UUri uri = new UUri(uAuthority, uEntity, uResource); - final String strUri = ShortUriSerializer.instance().serialize(uri); - assertEquals("s:/2/1", strUri); - } - - @Test - @DisplayName("Test serialize with UResource that is missing uresource id") - public void test_serialize_missing_uresource_id() { - final UAuthority uAuthority = UAuthority.local(); - final UEntity uEntity = UEntity.microFormat((short)2, 1); - final UResource uResource = UResource.longFormat("raise"); - final UUri uri = new UUri(uAuthority, uEntity, uResource); - final String strUri = ShortUriSerializer.instance().serialize(uri); - assertEquals("s:/2/1", strUri); - } - - @Test - @DisplayName("Test deserialize null string") - public void test_deserialize_null_string() { - final UUri uri = ShortUriSerializer.instance().deserialize(null); - assertEquals(UUri.empty(), uri); - } - - @Test - @DisplayName("Test deserialize empty string") - public void test_deserialize_empty_string() { - final UUri uri = ShortUriSerializer.instance().deserialize(""); - assertEquals(UUri.empty(), uri); - } - - @Test - @DisplayName("Test deserialize string with no slashes") - public void test_deserialize_string_with_no_slashes() { - final UUri uri = ShortUriSerializer.instance().deserialize("abc"); - assertEquals(UUri.empty(), uri); - } - - @Test - @DisplayName("Test deserialize string with one slash") - public void test_deserialize_string_with_one_slash() { - final UUri uri = ShortUriSerializer.instance().deserialize("s:/"); - assertEquals(UUri.empty(), uri); - } - - @Test - @DisplayName("Test deserialize string with two slashes") - public void test_deserialize_string_with_two_slashes() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://"); - assertTrue(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - } - - @Test - @DisplayName("Test deserialize string with three slashes") - public void test_deserialize_string_with_three_slashes() { - final UUri uri = ShortUriSerializer.instance().deserialize("s:///"); - assertTrue(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - } - - @Test - @DisplayName("Test deserialize string with four slashes") - public void test_deserialize_string_with_four_slashes() { - final UUri uri = ShortUriSerializer.instance().deserialize("s:////"); - assertTrue(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - } - - - @Test - @DisplayName("Test deserialize string with without any parts") - public void test_deserialize_string_without_any_parts() { - final UUri uri = ShortUriSerializer.instance().deserialize("s:"); - assertTrue(uri.isEmpty()); - } - - - @Test - @DisplayName("Test deserialize string with only device part of authority and no entity or resource") - public void test_deserialize_string_with_only_device_part_ofauthority_and_no_entity_or_resource() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu"); - assertFalse(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", uri.uAuthority().device().orElse("")); - assertFalse(uri.uAuthority().domain().isPresent()); - assertTrue(uri.uEntity().isEmpty()); - assertTrue(uri.uResource().isEmpty()); - } - @Test - @DisplayName("Test deserialize string with authority and no entity or resource") - public void test_deserialize_string_with_authority_and_no_entity_or_resource() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin"); - assertFalse(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", uri.uAuthority().device().orElse("")); - assertEquals("vin", uri.uAuthority().domain().orElse("")); - assertTrue(uri.uEntity().isEmpty()); - assertTrue(uri.uResource().isEmpty()); - } - - @Test - @DisplayName("Test deserialize string with authority and entity and no resource") - public void test_deserialize_string_with_authority_and_entity_and_no_resource() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2/1"); - assertFalse(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", uri.uAuthority().device().orElse("")); - assertEquals("vin", uri.uAuthority().domain().orElse("")); - assertFalse(uri.uEntity().isEmpty()); - assertEquals((short)2, uri.uEntity().id().orElse((short)0)); - assertEquals(1, uri.uEntity().version().orElse(0)); - assertTrue(uri.uResource().isEmpty()); - } - - @Test - @DisplayName("Test deserialize string with authority and missing UEntity but with uResource") - public void test_deserialize_string_with_authority_and_missing_entity_with_resource() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin///2"); - assertFalse(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", uri.uAuthority().device().orElse("")); - assertEquals("vin", uri.uAuthority().domain().orElse("")); - assertTrue(uri.uEntity().isEmpty()); - assertFalse(uri.uResource().isEmpty()); - assertTrue(uri.uResource().id().isPresent()); - assertEquals(uri.uResource().id().get(), (short)2); - } - - @Test - @DisplayName("Test deserialize remote string without scheme") - public void test_deserialize_remote_string_without_scheme() { - final UUri uri = ShortUriSerializer.instance().deserialize("//vcu.vin/2/1/2"); - assertTrue(uri.isEmpty()); - } - - @Test - @DisplayName("Test deserialize local string without scheme") - public void test_deserialize_local_string_without_scheme() { - final UUri uri = ShortUriSerializer.instance().deserialize("/2/1/2"); - assertTrue(uri.isEmpty()); - } - - @Test - @DisplayName("Test deserialize remote string with UEntity id but missing UEntity version") - public void test_deserialize_remote_string_with_uentityid_without_version() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2"); - assertFalse(uri.isEmpty()); - assertTrue(uri.uAuthority().isMarkedRemote()); - assertEquals("vcu", uri.uAuthority().device().orElse("")); - assertEquals("vin", uri.uAuthority().domain().orElse("")); - assertFalse(uri.uEntity().isEmpty()); - assertEquals((short)2, uri.uEntity().id().orElse((short)0)); - assertTrue(uri.uResource().isEmpty()); - } - - @Test - @DisplayName("Test deserialize string with invalid uEntity_id") - public void test_deserialize_string_with_invalid_uentity_id() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/abc/1/2"); - assertTrue(uri.isEmpty()); - } - - @Test - @DisplayName("Test deserialize string with invalid uEntity_version") - public void test_deserialize_string_with_invalid_uentity_version() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2/abc/2"); - assertTrue(uri.isEmpty()); - } - - @Test - @DisplayName("Test deserialize string with invalid uResource_id") - public void test_deserialize_string_with_invalid_uresource_id() { - final UUri uri = ShortUriSerializer.instance().deserialize("s://vcu.vin/2/1/abc"); - assertTrue(uri.isEmpty()); - } - -} diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java deleted file mode 100644 index 782e5469..00000000 --- a/src/test/java/org/eclipse/uprotocol/uri/validator/UUriValidatorTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ - -package org.eclipse.uprotocol.uri.validator; - - -import org.eclipse.uprotocol.transport.datamodel.UStatus; -import org.eclipse.uprotocol.transport.datamodel.UStatus.Code; -import org.eclipse.uprotocol.uri.datamodel.UAuthority; -import org.eclipse.uprotocol.uri.datamodel.UEntity; -import org.eclipse.uprotocol.uri.datamodel.UResource; -import org.eclipse.uprotocol.uri.datamodel.UUri; -import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class UUriValidatorTest { - - @Test - @DisplayName("Test validate blank uri") - public void test_validate_blank_uri() { - final UUri uri = LongUriSerializer.instance().deserialize(null); - final UStatus status = UriValidator.validate(uri); - assertTrue(uri.isEmpty()); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); - } - - @Test - @DisplayName("Test validate uri with no device name") - public void test_validate_uri_with_no_entity_name() { - final UUri uri = LongUriSerializer.instance().deserialize("//"); - final UStatus status = UriValidator.validate(uri); - assertTrue(uri.isEmpty()); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); - } - - @Test - @DisplayName("Test validate uri with uEntity") - public void test_validate_uri_with_uEntity() { - final UUri uri = LongUriSerializer.instance().deserialize("/hartley"); - final UStatus status = UriValidator.validate(uri); - assertEquals(UStatus.ok(), status); - } - - @Test - @DisplayName("Test validate with malformed URI") - public void test_validate_with_malformed_uri() { - final UUri uri = LongUriSerializer.instance().deserialize("hartley"); - final UStatus status = UriValidator.validate(uri); - assertTrue(uri.isEmpty()); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); - } - - - @Test - @DisplayName("Test validate with blank UEntity Name") - public void test_validate_with_blank_uentity_name_uri() { - final UUri uri = new UUri(UAuthority.local(), UEntity.empty(), UResource.forRpcRequest("echo")); - final UStatus status = UriValidator.validate(uri); - assertFalse(uri.isEmpty()); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is missing uSoftware Entity name.", status.msg()); - } - - @Test - @DisplayName("Test validateRpcMethod with valid URI") - public void test_validateRpcMethod_with_valid_uri() { - final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.echo"); - final UStatus status = UriValidator.validateRpcMethod(uri); - assertEquals(UStatus.ok(), status); - } - - @Test - @DisplayName("Test validateRpcMethod with valid URI") - public void test_validateRpcMethod_with_invalid_uri() { - final UUri uri = LongUriSerializer.instance().deserialize("/hartley/echo"); - final UStatus status = UriValidator.validateRpcMethod(uri); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Invalid RPC method uri. Uri should be the method to be called, or method from response.", status.msg()); - } - - @Test - @DisplayName("Test validateRpcMethod with malformed URI") - public void test_validateRpcMethod_with_malformed_uri() { - final UUri uri = LongUriSerializer.instance().deserialize("hartley"); - final UStatus status = UriValidator.validateRpcMethod(uri); - assertTrue(uri.isEmpty()); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); - } - - @Test - @DisplayName("Test validateRpcResponse with valid URI") - public void test_validateRpcResponse_with_valid_uri() { - final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.response"); - final UStatus status = UriValidator.validateRpcResponse(uri); - assertEquals(UStatus.ok(), status); - } - - @Test - @DisplayName("Test validateRpcResponse with malformed URI") - public void test_validateRpcResponse_with_malformed_uri() { - final UUri uri = LongUriSerializer.instance().deserialize("hartley"); - final UStatus status = UriValidator.validateRpcResponse(uri); - assertTrue(uri.isEmpty()); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Uri is empty.", status.msg()); - } - - @Test - @DisplayName("Test validateRpcResponse with rpc type") - public void test_validateRpcResponse_with_rpc_type() { - final UUri uri = LongUriSerializer.instance().deserialize("/hartley//dummy.wrong"); - final UStatus status = UriValidator.validateRpcResponse(uri); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Invalid RPC response type.", status.msg()); - } - - @Test - @DisplayName("Test validateRpcResponse with invalid rpc response type") - public void test_validateRpcResponse_with_invalid_rpc_response_type() { - final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.wrong"); - final UStatus status = UriValidator.validateRpcResponse(uri); - assertEquals(Code.INVALID_ARGUMENT.value(), status.getCode()); - assertEquals("Invalid RPC response type.", status.msg()); - } - -} diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java new file mode 100644 index 00000000..8fea4c89 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/UriValidatorTest.java @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2023 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. + */ + +package org.eclipse.uprotocol.uri.validator; + + +import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; +import org.eclipse.uprotocol.v1.UUri; +import org.eclipse.uprotocol.validation.ValidationResult; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class UriValidatorTest { + + @Test + @DisplayName("Test validate blank uri") + public void test_validate_blank_uri() { + final UUri uri = LongUriSerializer.instance().deserialize(null); + final ValidationResult status = UriValidator.validate(uri); + assertTrue(UriValidator.isEmpty(uri)); + assertEquals("Uri is empty.", status.getMessage()); + } + + @Test + @DisplayName("Test validate uri with no device name") + public void test_validate_uri_with_no_entity_getName() { + final UUri uri = LongUriSerializer.instance().deserialize("//"); + final ValidationResult status = UriValidator.validate(uri); + assertTrue(UriValidator.isEmpty(uri)); + assertEquals("Uri is empty.", status.getMessage()); + } + + @Test + @DisplayName("Test validate uri with uEntity") + public void test_validate_uri_with_getEntity() { + final UUri uri = LongUriSerializer.instance().deserialize("/hartley"); + final ValidationResult status = UriValidator.validate(uri); + assertEquals(ValidationResult.success(), status); + } + + @Test + @DisplayName("Test validate with malformed URI") + public void test_validate_with_malformed_uri() { + final UUri uri = LongUriSerializer.instance().deserialize("hartley"); + final ValidationResult status = UriValidator.validate(uri); + assertTrue(UriValidator.isEmpty(uri)); + assertEquals("Uri is empty.", status.getMessage()); + } + + + @Test + @DisplayName("Test validate with blank UEntity Name") + public void test_validate_with_blank_uentity_name_uri() { + final ValidationResult status = UriValidator.validate(UUri.getDefaultInstance()); + assertTrue(status.isFailure()); + assertEquals("Uri is empty.", status.getMessage()); + } + + @Test + @DisplayName("Test validateRpcMethod with valid URI") + public void test_validateRpcMethod_with_valid_uri() { + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.echo"); + final ValidationResult status = UriValidator.validateRpcMethod(uri); + assertEquals(ValidationResult.success(), status); + } + + @Test + @DisplayName("Test validateRpcMethod with valid URI") + public void test_validateRpcMethod_with_invalid_uri() { + final UUri uri = LongUriSerializer.instance().deserialize("/hartley/echo"); + final ValidationResult status = UriValidator.validateRpcMethod(uri); + assertTrue(status.isFailure()); + assertEquals("Uri is empty.", status.getMessage()); + } + + @Test + @DisplayName("Test validateRpcMethod with malformed URI") + public void test_validateRpcMethod_with_malformed_uri() { + final UUri uri = LongUriSerializer.instance().deserialize("hartley"); + final ValidationResult status = UriValidator.validateRpcMethod(uri); + assertTrue(UriValidator.isEmpty(uri)); + assertEquals("Uri is empty.", status.getMessage()); + } + + @Test + @DisplayName("Test validateRpcResponse with valid URI") + public void test_validateRpcResponse_with_valid_uri() { + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.response"); + final ValidationResult status = UriValidator.validateRpcResponse(uri); + assertEquals(ValidationResult.success(), status); + } + + @Test + @DisplayName("Test validateRpcResponse with malformed URI") + public void test_validateRpcResponse_with_malformed_uri() { + final UUri uri = LongUriSerializer.instance().deserialize("hartley"); + final ValidationResult status = UriValidator.validateRpcResponse(uri); + assertTrue(UriValidator.isEmpty(uri)); + assertEquals("Uri is empty.", status.getMessage()); + } + + @Test + @DisplayName("Test validateRpcResponse with rpc type") + public void test_validateRpcResponse_with_rpc_type() { + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//dummy.wrong"); + final ValidationResult status = UriValidator.validateRpcResponse(uri); + assertTrue(status.isFailure()); + assertEquals("Invalid RPC response type.", status.getMessage()); + } + + @Test + @DisplayName("Test validateRpcResponse with invalid rpc response type") + public void test_validateRpcResponse_with_invalid_rpc_response_type() { + final UUri uri = LongUriSerializer.instance().deserialize("/hartley//rpc.wrong"); + final ValidationResult status = UriValidator.validateRpcResponse(uri); + assertTrue(status.isFailure()); + assertEquals("Invalid RPC response type.", status.getMessage()); + } + + @Test + @DisplayName("Test validate topic uri with version, when it is valid microRemote") + void test_topic_uri_with_version_when_it_is_valid_remote() { + + final String uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate topic uri no version, when it is valid microRemote") + void test_topic_uri_no_version_when_it_is_valid_remote() { + + final String uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate topic uri with version, when it is valid local") + void test_topic_uri_with_version_when_it_is_valid_local() { + + final String uri = "/body.access/1/door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate topic uri no version, when it is valid local") + void test_topic_uri_no_version_when_it_is_valid_local() { + + final String uri = "/body.access//door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate topic uri is invalid when uri contains nothing but schema") + void test_topic_uri_invalid_when_uri_has_schema_only() { + + final String uri = ":"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate topic uri is invalid when uri contains empty use name local") + void test_topic_uri_invalid_when_uri_has_empty_use_name_local() { + + final String uri = "/"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate topic uri is invalid when uri is microRemote but missing authority") + void test_topic_uri_invalid_when_uri_is_remote_no_authority() { + + final String uri = "//"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate topic uri is invalid when uri is microRemote with use but missing authority") + void test_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() { + + final String uri = "///body.access/1/door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + + } + + @Test + @DisplayName("Test validate topic uri is invalid when uri has no use information") + void test_topic_uri_invalid_when_uri_is_missing_use_remote() { + + final String uri = "//VCU.myvin///door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate microRemote topic uri is invalid when uri is missing use name") + void test_topic_uri_invalid_when_uri_is_missing_use_name_remote() { + + final String uri = "/1/door.front_left#Door"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate local topic uri is invalid when uri is missing use name") + void test_topic_uri_invalid_when_uri_is_missing_use_name_local() { + + final String uri = "//VCU.myvin//1"; + + final ValidationResult status = UriValidator.validate(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + + @Test + @DisplayName("Test validate rpc topic uri with version, when it is valid microRemote") + void test_rpc_topic_uri_with_version_when_it_is_valid_remote() { + + final String uri = "//bo.cloud/petapp/1/rpc.response"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc topic uri no version, when it is valid microRemote") + void test_rpc_topic_uri_no_version_when_it_is_valid_remote() { + + final String uri = "//bo.cloud/petapp//rpc.response"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc topic uri with version, when it is valid local") + void test_rpc_topic_uri_with_version_when_it_is_valid_local() { + + final String uri = "/petapp/1/rpc.response"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc topic uri no version, when it is valid local") + void test_rpc_topic_uri_no_version_when_it_is_valid_local() { + + final String uri = "/petapp//rpc.response"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc topic uri is invalid when uri contains nothing but schema") + void test_rpc_topic_uri_invalid_when_uri_has_schema_only() { + + final String uri = ":"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc topic uri with version, when it is local but missing rpc.respons") + void test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_local() { + + final String uri = "/petapp/1/dog"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc topic uri with version, when it is microRemote but missing rpc.respons") + void test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_remote() { + + final String uri = "//petapp/1/dog"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote but missing authority") + void test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority() { + + final String uri = "//"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote with use but missing authority") + void test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() { + + final String uri = "///body.access/1"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc topic uri is invalid when uri has no use information") + void test_rpc_topic_uri_invalid_when_uri_is_missing_use() { + + final String uri = "//VCU.myvin"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate microRemote rpc topic uri is invalid when uri is missing use name") + void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_remote() { + + final String uri = "/1"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate local rpc topic uri is invalid when uri is missing use name") + void test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() { + + final String uri = "//VCU.myvin//1"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + + @Test + @DisplayName("Test validate rpc method uri with version, when it is valid microRemote") + void test_rpc_method_uri_with_version_when_it_is_valid_remote() { + + final String uri = "//VCU.myvin/body.access/1/rpc.UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc method uri no version, when it is valid microRemote") + void test_rpc_method_uri_no_version_when_it_is_valid_remote() { + + final String uri = "//VCU.myvin/body.access//rpc.UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc method uri with version, when it is valid local") + void test_rpc_method_uri_with_version_when_it_is_valid_local() { + + final String uri = "/body.access/1/rpc.UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc method uri no version, when it is valid local") + void test_rpc_method_uri_no_version_when_it_is_valid_local() { + + final String uri = "/body.access//rpc.UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isSuccess()); + } + + @Test + @DisplayName("Test validate rpc method uri is invalid when uri contains nothing but schema") + void test_rpc_method_uri_invalid_when_uri_has_schema_only() { + + final String uri = ":"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc method uri with version, when it is local but not an rpc method") + void test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_local() { + + final String uri = "/body.access//UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc method uri with version, when it is microRemote but not an rpc method") + void test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_remote() { + + final String uri = "//body.access/1/UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc method uri is invalid when uri is microRemote but missing authority") + void test_rpc_method_uri_invalid_when_uri_is_remote_no_authority() { + + final String uri = "//"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate rpc method uri is invalid when uri is microRemote with use but missing authority") + void test_rpc_method_uri_invalid_when_uri_is_remote_no_authority_with_use() { + + final String uri = "///body.access/1/rpc.UpdateDoor"; + + final UUri uuri = LongUriSerializer.instance().deserialize(uri); + final ValidationResult status = UriValidator.validateRpcMethod(uuri); + assertEquals("", uuri.toString()); + assertTrue(status.isFailure()); + + } + + @Test + @DisplayName("Test validate rpc method uri is invalid when uri has no use information") + void test_rpc_method_uri_invalid_when_uri_is_missing_use() { + + final String uri = "//VCU.myvin"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate local rpc method uri is invalid when uri is missing use name") + void test_rpc_method_uri_invalid_when_uri_is_missing_use_name_local() { + + final String uri = "/1/rpc.UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + + assertTrue(status.isFailure()); + } + + @Test + @DisplayName("Test validate microRemote rpc method uri is invalid when uri is missing use name") + void test_rpc_method_uri_invalid_when_uri_is_missing_use_name_remote() { + + final String uri = "//VCU.myvin//1/rpc.UpdateDoor"; + + final ValidationResult status = UriValidator.validateRpcMethod(LongUriSerializer.instance().deserialize(uri)); + assertTrue(status.isFailure()); + } + +} diff --git a/src/test/java/org/eclipse/uprotocol/uri/validator/uris.json b/src/test/java/org/eclipse/uprotocol/uri/validator/uris.json new file mode 100644 index 00000000..ebeb4905 --- /dev/null +++ b/src/test/java/org/eclipse/uprotocol/uri/validator/uris.json @@ -0,0 +1,38 @@ +{ + "validUris" : [ + "/", + "//", + "//vcu", + "//vcu.vin/", + "/hartley", + "/hartley//", + "hartley/0", + "/1", + "/body.access/1", + "/body.access/1/door.front_left#Door", + "//vcu.vin/body.access/1/door.front_left#Door", + "/body.access/1/rpc.OpenWindow", + "/body.access/1/rpc.response" + ], + "invalidUris" : [ + {"uri": "", "reason" : "Empty Uri"}, + {"uri": ":", "reason": "Contains only schema"}, + {"uri": "///", "reason" : "Empty Authority"}, + {"uri": "////", "reason" : "Empty Uri"}, + {"uri": "1", "reason" : "Invalid Uri, must begin with \"\/\""}, + {"uri": "a", "reason" : "Invalid Uri, must begin with \"\/\""}, + {"uri": "/1", "reason" : "Invalid Uri, must begin with \"\/\""} + ], + "validRpcUris": [ + "/petapp/1/rpc.OpenWindow", + "/petapp/1.2/rpc.response" + ], + "invalidRpcUris" : [ + {"uri": "/petapp//", "reason" : "Missing uE version"}, + {"uri": "/petapp", "reason" : "Missing uE version"}, + {"uri": "/petapp/1/", "reason" : "Missing RPC Method Name"}, + {"uri": "/petapp/1/rpc", "reason" : "Missing RPC Method Name"}, + {"uri": "/petapp/1/dummy", "reason" : "Missing RPC Method Name"}, + {"uri": "/petapp/1/rpc_dummy", "reason" : "Missing RPC Method Name"} + ] +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java b/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java index 07acb962..ecaacc4c 100644 --- a/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.java @@ -21,10 +21,11 @@ package org.eclipse.uprotocol.uuid.validator; -import org.eclipse.uprotocol.cloudevent.validate.ValidationResult; import org.eclipse.uprotocol.uuid.factory.UUIDFactory; import org.eclipse.uprotocol.uuid.factory.UUIDUtils; import org.eclipse.uprotocol.uuid.validate.UuidValidator; +import org.eclipse.uprotocol.validation.ValidationResult; + import com.google.rpc.Code; import com.google.rpc.Status;