)' $INDEX_PATH | sed 's/ //g')
+ export COVERAGE_PERCENTAGE=$(printf "%.2f" "$COVERAGE_PERCENTAGE")
+ echo "COVERAGE_PERCENTAGE= $COVERAGE_PERCENTAGE" >> $GITHUB_ENV
+ echo "COVERAGE_PERCENTAGE: $COVERAGE_PERCENTAGE"
+
+
+ - name: Upload JaCoCo Coverage report
+ uses: actions/upload-artifact@v3
+ with:
+ name: coverage-report
+ path: target/site/jacoco
+
+ - name: Generate coverage comment
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const COVERAGE_PERCENTAGE = `${{ env.COVERAGE_PERCENTAGE }}`;
+ const COVERAGE_REPORT_PATH = `https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/`;
+
+ fs.mkdirSync('./pr-comment', { recursive: true });
+
+ var pr_number = `${{ github.event.number }}`;
+ var body = `
+ Code coverage report is ready! :chart_with_upwards_trend:
+
+ - **Code Coverage Percentage:** ${COVERAGE_PERCENTAGE}%
+ - **Code Coverage Report:** [View Coverage Report](${COVERAGE_REPORT_PATH})
+ `;
+
+ fs.writeFileSync('./pr-comment/pr-number.txt', pr_number);
+ fs.writeFileSync('./pr-comment/body.txt', body);
+
+ - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
+ with:
+ name: pr-comment
+ path: pr-comment/
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b0b8572..a3f865c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -24,7 +24,7 @@ jobs:
uses: actions/setup-java@v3
with: # configure settings.xml
distribution: 'temurin'
- java-version: '11'
+ java-version: '17'
server-id: ossrh
server-username: OSSRH_USER
server-password: OSSRH_PASSWORD
diff --git a/NOTICE.adoc b/NOTICE.adoc
index e7d6c4c..a1f706f 100644
--- a/NOTICE.adoc
+++ b/NOTICE.adoc
@@ -27,7 +27,6 @@ SPDX-License-Identifier: Apache-2.0
The following are libraries that uProtocol project uses:
-* http://cloudevents.io
* http://protobuf.dev
NOTE: Please refer to link:pom.xml[] for more information of library dependencies
\ No newline at end of file
diff --git a/README.adoc b/README.adoc
index 719ec44..ea09481 100644
--- a/README.adoc
+++ b/README.adoc
@@ -24,45 +24,24 @@ To pull the Library from maven central, setting ${uprotocol.version} to the late
=== Using The Library
-.Package Folders
-[#pkg-folders,width=100%,cols="20%,80%",options="header"]
-|===
-
-| Folder | Purpose
-
-| `*builder*` or `*factory*`
-| Contains factory methods for creating uProtocol data types
-
-| `*serializer*`
-| Contains serializers to convert the objects into byte or string form representation of said object
-
-| `*validator*`
-| Contains validators to validate the data types and report errors if the objects are missing or incorrect
-
-|===
-
-
.SDK Packages
[#sdk-packages,width=100%,cols="20%,80%",options="header"]
|===
| Package | Purpose
+| xref:src/main/kotlin/org/eclipse/uprotocol/communication/README.adoc[`*communication*`]
+| Top level client-facing https://github.com/eclipse-uprotocol/up-spec/tree/main/up-l2[communication layer (uP-L2)] interfaces that applications and services use to implement the publisher/subscriber, notification, and RPC patterns on top of the transport layer (uTransport) API.
+
| link:src/main/kotlin/org/eclipse/uprotocol/uri/README.adoc[`*uuri*`]
-| Uniform Resource Identifier (RFC3986), how uProtocol addresses things (devices, software, methods, topics, etc...) on the network
+| Builders, validators, and serializers for uProtocol addressing scheme (UUri).
| link:src/main/kotlin/org/eclipse/uprotocol/uuid/README.adoc[`*uuid*`]
| Identifier used to uniquely identify (and timestamp) messages that are sent
-| link:src/main/java/org/eclipse/uprotocol/transport/README.adoc[`*transport*`]
-| Interface declaration used for bidirectional point-2-point communication between uEs. This interface is then implemented by https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/upclient.adoc[uPClient] libraries for a given underlining transport (ex. Binder, MQTT, Zenoh, SOME/IP, DDS, HTTP, etc…)
-
-| link:src/main/kotlin/org/eclipse/uprotocol/cloudevent/README.adoc[`*cloudevent*`]
-| Common way to represent uProtocol messages using CloudEvent data model used by some transports (ex. MQTT, HTTP, etc…)
-
-| link:src/main/java/org/eclipse/uprotocol/rpc/README.adoc[`*rpc*`]
-| RPC client and server-side interfaces that are to be implemented by uLink libraries
+| link:src/main/kotlin/org/eclipse/uprotocol/transport/README.adoc[`*transport*`]
+| https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/README.adoc[uP-L1 Transport Layer] interface and data model that wraps communication middlewares like zenoh, mqtt, http, etc... into a thin and simple to use transport interface. This model is used by the communication layer (uP-L2) to send and receive messages and transports are expected to implement the link:src/main/kotlin/org/eclipse/uprotocol/transport/UTransport.kt[uTransport] interface.
|===
diff --git a/pom.xml b/pom.xml
index 24858b8..126e50c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,35 +15,26 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
-
org.eclipse.uprotocolup-kotlinKotlin Library for uProtocolLanguage specific uProtocol library for building and using UUri, UUID, UAttributes, UTransport, and more
- 1.5.7-SNAPSHOT
+ 0.1.8-SNAPSHOTjarhttps://github.com/eclipse-uprotocol/up-kotlin/1.9.21UTF-8
- 11
- 11UTF-8
-
-
1.9.15.9.14.123.0.0-M5
-
2.6.18
-
- 2.4.2
-
3.21.10
- uprotocol-core-api-1.5.7
+ main
@@ -125,8 +116,23 @@
report
+
+
+
+ org/eclipse/uprotocol/core/**
+ org/eclipse/uprotocol/v1/**
+
+
+
+
+ **/transport/**
+ **/uri/**
+ **/uuid/**
+ **/validation/**
+
+
@@ -210,8 +216,8 @@
clone--branch${git.tag.name}
- https://github.com/eclipse-uprotocol/up-core-api.git
- ${project.build.directory}/up-core-api
+ https://github.com/eclipse-uprotocol/up-spec.git
+ ${project.build.directory}/up-spec
@@ -228,7 +234,7 @@
git
- ${project.build.directory}/up-core-api
+ ${project.build.directory}/up-spec/up-core-apipullorigin
@@ -269,7 +275,7 @@
11
- 3.10.1
+ 3.13.0org.xolstice.maven.plugins
@@ -294,8 +300,7 @@
- ${project.build.directory}/up-core-api/uprotocol
-
+ ${project.build.directory}/up-spec/up-core-apicom.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
@@ -310,12 +315,6 @@
kotlin-stdlib${kotlin.version}
-
- io.cloudevents
- cloudevents-protobuf
- 2.4.2
-
-
com.google.errorprone
@@ -323,7 +322,6 @@
2.11.0
-
org.checkerframeworkchecker-qual
@@ -338,16 +336,6 @@
pom
-
-
-
- io.cloudevents
- cloudevents-bom
- ${cloudevents.version}
- pom
- import
-
-
nl.jqno.equalsverifierequalsverifier
@@ -401,27 +389,6 @@
test
-
-
- io.cloudevents
- cloudevents-protobuf
-
-
-
-
-
- io.cloudevents
- cloudevents-core
-
-
- io.cloudevents
- cloudevents-api
-
-
- io.cloudevents
- cloudevents-json-jackson
-
-
com.google.protobufprotobuf-kotlin
@@ -470,13 +437,13 @@
-
-
- dash-licenses-snapshots
- https://repo.eclipse.org/content/repositories/dash-licenses-releases/
-
+
+
+
+
+
-
+
release
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/README.adoc b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/README.adoc
deleted file mode 100644
index 7c61f24..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/README.adoc
+++ /dev/null
@@ -1,109 +0,0 @@
-= 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).
-
-
-=== CloudEventFactory
-Factory class that builds the various types of CloudEvents for uProtocol (publish, notification, request, response)
-
-== Examples
-
-
-=== Building an uuri
-[source,kotlin]
-----
- val use: UEntity = uEntity { name = "body.access" }
- val res: UResource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- val uri: UUri = uUri {
- entity = use
- resource = res
- }
- source: String = LongUriSerializer.instance().serialize(uri)
-----
-
-=== Build proto payload
-[source,kotlin]
-
-----
-
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent = io.cloudevents.v1.proto.CloudEvent.newBuilder()
- .setSpecVersion("1.0")
- .setId("hello")
- .setSource("https://example.com")
- .setType("example.demo")
- .setProtoData(Any.newBuilder().build())
- .build()
- val proto_payload: Any = Any.pack(cloudEventProto)
-
-
-----
-
-=== Build UCloudEvent Attributes
-[source,kotlin]
-
-----
-
-val uCloudEventAttributes: UCloudEventAttributes = UCloudEventAttributes.UCloudEventAttributesBuilder()
- .withHash("somehash")
- .withPriority(UPriority.UPRIORITY_CS1)
- .withTtl(3)
- .withToken("someOAuthToken")
- .build()
-
-----
-
-=== Build publish cloud event
-[source,kotlin]
-
-----
-
-
-val cloudEvent: CloudEvent = CloudEventFactory.publish(source, protoPayload, uCloudEventAttributes)
-# test all attributes
- assertEquals("1.0", cloudEvent.getSpecVersion().toString())
- assertNotNull(cloudEvent.getId())
- assertEquals(source, cloudEvent.getSource().toString())
- assertEquals(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH), cloudEvent.getType())
- assertFalse(cloudEvent.getExtensionNames().contains("sink"))
- assertEquals("somehash", cloudEvent.getExtension("hash"))
- assertEquals(UPriority.UPRIORITY_CS1.name(), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.getData()).toBytes())
-
-
-----
-
-
-=== Build cloudevent ↔ umessage
-[source,kotlin]
-
-----
-
-val result: UMessage = UCloudEvent.toMessage(cloudEvent)
-assertNotNull(result)
-assertTrue(UCloudEvent.getRequestId(cloudEvent).isPresent())
-assertTrue(UCloudEvent.getTtl(cloudEvent).isPresent())
-assertEquals(UCloudEvent.getTtl(cloudEvent), result.getAttributes().getTtl())
-assertEquals(UCloudEvent.getPayload(cloudEvent).toByteString(),result.getPayload().getValue())
-assertEquals(UCloudEvent.getSource(cloudEvent),LongUriSerializer.instance().serialize(result.getSource()))
-assertTrue(UCloudEvent.getPriority(cloudEvent).isPresent())
-assertEquals(UCloudEvent.getPriority(cloudEvent), String.valueOf(result.getAttributes().getPriority()))
-
-val cloudEvent1: CloudEvent = UCloudEvent.fromMessage(result)
-assertEquals(cloudEvent,cloudEvent1)
-
-
-----
-
-
-
-
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventAttributes.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventAttributes.kt
deleted file mode 100644
index e1aa57f..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventAttributes.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.datamodel
-
-import org.eclipse.uprotocol.v1.UPriority
-
-/**
- * Specifies the properties that can configure the UCloudEvent.
- * @param hash An HMAC generated on the data portion of the CloudEvent message 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 traceparent An identifier used to correlate observability across related events.
- */
-data class UCloudEventAttributes internal constructor(
- val hash: String? = null,
- val priority: UPriority? = null,
- val ttl: Int? = null,
- val token: String? = null,
- val traceparent: String? = null
-) {
- private constructor(builder: UCloudEventAttributesBuilder) : this(
- if (builder.hash.isNullOrBlank()) null else builder.hash,
- builder.priority,
- builder.ttl,
- if (builder.token.isNullOrBlank()) null else builder.token,
- builder.traceparent
- )
-
- /**
- * An HMAC generated on the data portion of the CloudEvent message using the device key.
- */
- val isEmpty: Boolean
- /**
- * Indicates that there are no added additional attributes to configure when building a CloudEvent.
- * @return Returns true if this attributes container is an empty container and has no valuable information in building a CloudEvent.
- */
- get() = hash == null && priority == null && ttl == null && token == null && traceparent == null
-
- /**
- * Builder for constructing the UCloudEventAttributes.
- */
- class UCloudEventAttributesBuilder @PublishedApi internal constructor() {
- /**
- * add an HMAC generated on the data portion of the CloudEvent message using the device key.
- */
- var hash: String? = null
-
- /**
- * add a uProtocol Prioritization classifications.
- */
- var priority: UPriority? = null
-
- /**
- * add 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.
- */
- var ttl: Int? = null
-
- /**
- * Add an Oauth2 access token to perform the access request defined in the request message.
- */
- var token: String? = null
-
- /**
- * Add an identifier used to correlate observability across related events.
- */
- var traceparent: String? = null
-
-
- /**
- * Construct the UCloudEventAttributes from the builder.
- * @return Returns a constructed UProperty.
- */
- @JvmSynthetic
- @PublishedApi
- internal fun build(): UCloudEventAttributes {
- // validation if needed
- return UCloudEventAttributes(this)
- }
- }
-
- companion object {
- val EMPTY = UCloudEventAttributes()
-
- @JvmName("-initializeUCloudEventAttributes")
- inline fun uCloudEventAttributes(block: UCloudEventAttributesBuilder.() -> Unit) =
- UCloudEventAttributesBuilder().apply(block).build()
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.kt
deleted file mode 100644
index eadc94d..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactory.kt
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.factory
-
-import com.google.protobuf.Any
-import com.google.protobuf.Empty
-import io.cloudevents.CloudEvent
-import io.cloudevents.core.builder.CloudEventBuilder
-import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uuid.factory.UUIDV8
-import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer
-import org.eclipse.uprotocol.v1.UMessageType
-import org.eclipse.uprotocol.v1.UUID
-import org.eclipse.uprotocol.v1.UUri
-import java.net.URI
-
-/**
- * A factory is a part of the software has methods to generate concrete objects, usually of the same type or interface.
- * CloudEvents is a specification for describing events in a common way. We will use CloudEvents
- * to formulate all kinds of events (messages) that will be sent to and from devices.
- * The CloudEvent factory knows how to generate CloudEvents of the 4 core types: req.v1, res.v1, pub.v1, and file.v1
- */
-object CloudEventFactory {
- /**
- * Create a CloudEvent for an event for the use case of: RPC Request message.
- *
- * @param applicationUriForRPC The [Uri] for the application requesting the RPC.
- * @param serviceMethodUri The [Uri] for the method to be called on the service Ex.: :/body.access/1/rpc.UpdateDoor
- * @param protoPayload Protobuf Any object with the Message command to be executed on the sink service.
- * @param attributes Additional attributes such as ttl, hash, priority and token.
- * @return Returns an request CloudEvent.
- */
- fun request(
- applicationUriForRPC: Uri,
- serviceMethodUri: Uri,
- protoPayload: Any,
- attributes: UCloudEventAttributes
- ): CloudEvent {
- val id = generateCloudEventId()
- return buildBaseCloudEvent(
- id,
- applicationUriForRPC,
- protoPayload.toByteArray(),
- protoPayload.typeUrl,
- attributes
- )
- .withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_REQUEST))
- .withExtension("sink", URI.create(serviceMethodUri.value))
- .build()
- }
-
- /**
- * Create a CloudEvent for an event for the use case of: RPC Response message.
- *
- * @param applicationUriForRPC The destination of the response. The [Uri] for the original application that requested the RPC and this response is for.
- * @param serviceMethodUri The [Uri] for the method that was called on the service Ex.: :/body.access/1/rpc.UpdateDoor
- * @param requestId The cloud event id from the original request cloud event that this response if for.
- * @param protoPayload The protobuf serialized response message as defined by the application interface or the
- * google.rpc.Status message containing the details of an error.
- * @param attributes Additional attributes such as ttl, hash and priority.
- * @return Returns an response CloudEvent.
- */
- fun response(
- applicationUriForRPC: Uri,
- serviceMethodUri: Uri,
- requestId: String,
- protoPayload: Any,
- attributes: UCloudEventAttributes
- ): CloudEvent {
- val id = generateCloudEventId()
- return buildBaseCloudEvent(
- id,
- serviceMethodUri,
- protoPayload.toByteArray(),
- protoPayload.typeUrl,
- attributes
- )
- .withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- .withExtension("sink", URI.create(applicationUriForRPC.value))
- .withExtension("reqid", requestId)
- .build()
- }
-
- /**
- * Create a CloudEvent for an event for the use case of: RPC Response message that failed.
- *
- * @param applicationUriForRPC The destination of the response. The [Uri] for the original application that requested the RPC and this response is for.
- * @param serviceMethodUri The [Uri] for the method that was called on the service Ex.: :/body.access/1/rpc.UpdateDoor
- * @param requestId The cloud event id from the original request cloud event that this response if for.
- * @param communicationStatus A UCode value that indicates of a platform communication error while delivering this CloudEvent.
- * @param attributes Additional attributes such as ttl, hash and priority.
- * @return Returns a response CloudEvent Response for the use case of RPC Response message that failed.
- */
- fun failedResponse(
- applicationUriForRPC: Uri,
- serviceMethodUri: Uri,
- requestId: String,
- communicationStatus: Int,
- attributes: UCloudEventAttributes
- ): CloudEvent {
- val id = generateCloudEventId()
- val protoPayload: Any = Any.pack(Empty.getDefaultInstance())
- return buildBaseCloudEvent(
- id,
- serviceMethodUri,
- protoPayload.toByteArray(),
- protoPayload.typeUrl,
- attributes
- )
- .withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- .withExtension("sink", URI.create(applicationUriForRPC.value))
- .withExtension("reqid", requestId)
- .withExtension("commstatus", communicationStatus)
- .build()
- }
-
- /**
- * Create a CloudEvent for an event for the use case of: Publish generic message.
- *
- * @param source The [Uri] of the topic being published.
- * @param protoPayload protobuf Any object with the Message to be published.
- * @param attributes Additional attributes such as ttl, hash and priority.
- * @return Returns a publish CloudEvent.
- */
- fun publish(source: Uri, protoPayload: Any, attributes: UCloudEventAttributes): CloudEvent {
- val id = generateCloudEventId()
- return buildBaseCloudEvent(id, source, protoPayload.toByteArray(), protoPayload.typeUrl, attributes)
- .withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .build()
- }
-
- /**
- * Create a CloudEvent for an event for the use case of: Publish a notification message.
- * A published event containing the sink (destination) is often referred to as a notification, it is an event sent to a specific consumer.
- *
- * @param source The [Uri] of the topic being published.
- * @param sink The [Uri] of the destination of this notification.
- * @param protoPayload protobuf Any object with the Message to be published.
- * @param attributes Additional attributes such as ttl, hash and priority.
- * @return Returns a publish CloudEvent.
- */
- fun notification(
- source: Uri,
- sink: Uri,
- protoPayload: Any,
- attributes: UCloudEventAttributes
- ): CloudEvent {
- val id = generateCloudEventId()
- return buildBaseCloudEvent(id, source, protoPayload.toByteArray(), protoPayload.typeUrl, attributes)
- .withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withExtension("sink", URI.create(sink.value))
- .build()
- }
-
- /**
- * @return Returns a UUIDv8 id.
- */
- private fun generateCloudEventId(): String {
- val uuid: UUID = UUIDV8()
- return LongUuidSerializer.INSTANCE.serialize(uuid)
- }
-
- /**
- * Base CloudEvent builder that is the same for all CloudEvent types.
- *
- * @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 [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.typeUrl` 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
- * were configured.
- * @return Returns a CloudEventBuilder that can be additionally configured and then by calling .build() construct a CloudEvent
- * ready to be serialized and sent to the transport layer.
- */
- fun buildBaseCloudEvent(
- id: String?,
- source: Uri,
- protoPayloadBytes: ByteArray,
- protoPayloadSchema: String?,
- attributes: UCloudEventAttributes
- ): CloudEventBuilder {
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1()
- .withId(id)
- .withSource(URI.create(source.value)) /* Not needed:
- .withDataContentType(PROTOBUF_CONTENT_TYPE)
- .withDataSchema(URI.create(protoPayloadSchema))
- */
- .withData(protoPayloadBytes)
- attributes.ttl?.let { ttl -> cloudEventBuilder.withExtension("ttl", ttl) }
- attributes.priority?.let { priority ->
- cloudEventBuilder.withExtension(
- "priority",
- UCloudEvent.getCeName(priority.valueDescriptor)
- )
- }
- attributes.hash?.let { hash -> cloudEventBuilder.withExtension("hash", hash) }
- attributes.token?.let { token -> cloudEventBuilder.withExtension("token", token) }
- attributes.traceparent?.let { traceparent: String ->
- cloudEventBuilder.withExtension("traceparent", traceparent)
- }
-
- return cloudEventBuilder
- }
-
- const val PROTOBUF_CONTENT_TYPE = "application/x-protobuf"
-}
-
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/factory/UCloudEvent.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/factory/UCloudEvent.kt
deleted file mode 100644
index 14f7327..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/factory/UCloudEvent.kt
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.factory
-
-import com.google.protobuf.Any
-import com.google.protobuf.Descriptors.EnumValueDescriptor
-import com.google.protobuf.InvalidProtocolBufferException
-import com.google.protobuf.Message
-import io.cloudevents.CloudEvent
-import io.cloudevents.CloudEventData
-import io.cloudevents.core.builder.CloudEventBuilder
-import org.eclipse.uprotocol.UprotocolOptions
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uuid.factory.getTime
-import org.eclipse.uprotocol.uuid.factory.isUuid
-import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer
-import org.eclipse.uprotocol.v1.*
-import java.net.URI
-import java.time.OffsetDateTime
-import java.time.temporal.ChronoUnit
-
-
-/**
- * Class to extract information from a CloudEvent.
- */
-object UCloudEvent {
- /**
- * Extract the source from a cloud event. The source is a mandatory attribute.
- * The CloudEvent constructor does not allow creating a cloud event without a source.
- * @param cloudEvent CloudEvent with source to be extracted.
- * @return Returns the String value of a CloudEvent source attribute.
- */
- fun getSource(cloudEvent: CloudEvent): String {
- return cloudEvent.source.toString()
- }
-
- /**
- * Extract the sink from a cloud event. The sink attribute is optional.
- * @param cloudEvent CloudEvent with sink to be extracted.
- * @return Returns a Uri String value of a CloudEvent sink attribute if it exists,
- * otherwise Null is returned.
- */
- fun getSink(cloudEvent: CloudEvent): Uri? {
- return extractStringValueFromExtension("sink", cloudEvent)?.let { Uri(it) }
- }
-
- /**
- * Extract the request id from a cloud event that is a response RPC CloudEvent. The attribute is optional.
- * @param cloudEvent the response RPC CloudEvent with request id to be extracted.
- * @return Returns a String value of a response RPC CloudEvent request id attribute if it exists,
- * otherwise Null is returned.
- */
- fun getRequestId(cloudEvent: CloudEvent): String? {
- return extractStringValueFromExtension("reqid", cloudEvent)
- }
-
- /**
- * Extract the hash attribute from a cloud event. The hash attribute is optional.
- * @param cloudEvent CloudEvent with hash to be extracted.
- * @return Returns a String value of a CloudEvent hash attribute if it exists,
- * otherwise Null is returned.
- */
- fun getHash(cloudEvent: CloudEvent): String? {
- return extractStringValueFromExtension("hash", cloudEvent)
- }
-
- /**
- * Extract the string value of the priority attribute from a cloud event. The priority attribute is optional.
- * @param cloudEvent CloudEvent with priority to be extracted.
- * @return Returns a String value of a CloudEvent priority attribute if it exists,
- * otherwise Null is returned.
- */
- fun getPriority(cloudEvent: CloudEvent): String? {
- return extractStringValueFromExtension("priority", cloudEvent)
- }
-
- /**
- * Extract the integer value of the ttl attribute from a cloud event. The ttl attribute is optional.
- * @param cloudEvent CloudEvent with ttl to be extracted.
- * @return Returns an Int value of a CloudEvent ttl attribute if it exists,
- * otherwise Null is returned.
- */
- fun getTtl(cloudEvent: CloudEvent): Int? {
- return extractStringValueFromExtension("ttl", cloudEvent)?.toInt()
- }
-
- /**
- * Extract the string value of the token attribute from a cloud event. The token attribute is optional.
- * @param cloudEvent CloudEvent with token to be extracted.
- * @return Returns a String value of a CloudEvent priority token if it exists,
- * otherwise Null is returned.
- */
- fun getToken(cloudEvent: CloudEvent): String? {
- return extractStringValueFromExtension("token", cloudEvent)
- }
-
-
- /**
- * Extract the string value of the traceparent attribute from a cloud event. The traceparent attribute is optional.
- * @param cloudEvent CloudEvent with traceparent to be extracted.
- * @return Returns a String value of a CloudEvent traceparent if it exists,
- * otherwise Null is returned.
- */
- fun getTraceparent(cloudEvent: CloudEvent): String? {
- return extractStringValueFromExtension("traceparent", cloudEvent)
- }
-
- /**
- * Fetch the UCode from the CloudEvent commstatus integer value. The communication status attribute is optional.
- * If there was a platform communication error that occurred while delivering this cloudEvent, it will be indicated in this attribute.
- * If the attribute does not exist, it is assumed that everything was UCode.OK_VALUE.
- * @param cloudEvent CloudEvent with the platformError to be extracted.
- * @return Returns a UCode that indicates of a platform communication error while delivering this CloudEvent or UCode.OK.
- */
- fun getCommunicationStatus(cloudEvent: CloudEvent): UCode {
- return try {
- UCode.forNumber(extractIntegerValueFromExtension("commstatus", cloudEvent) ?: UCode.OK_VALUE)
- } catch (e: Exception) {
- UCode.OK
- }
- }
-
- /**
- * Indication of a platform communication error that occurred while trying to deliver the CloudEvent.
- * @param cloudEvent CloudEvent to be queried for a platform delivery error.
- * @return returns true if the provided CloudEvent is marked with having a platform delivery problem.
- */
- fun hasCommunicationStatusProblem(cloudEvent: CloudEvent): Boolean {
- return getCommunicationStatus(cloudEvent) != UCode.OK
- }
-
- /**
- * Returns a new CloudEvent from the supplied CloudEvent, with the platform communication added.
- * @param cloudEvent CloudEvent that the platform delivery error will be added.
- * @param communicationStatus the platform delivery error UCode to add to the CloudEvent.
- * @return Returns a new CloudEvent from the supplied CloudEvent, with the platform communication added.
- */
- fun addCommunicationStatus(cloudEvent: CloudEvent, communicationStatus: Int?): CloudEvent {
- if (communicationStatus == null) {
- return cloudEvent
- }
- val builder: CloudEventBuilder = CloudEventBuilder.v1(cloudEvent)
- builder.withExtension("commstatus", communicationStatus)
- return builder.build()
- }
-
- /**
- * Extract the timestamp from the UUIDV8 CloudEvent ID, with Unix epoch as the
- * @param cloudEvent The CloudEvent with the timestamp to extract.
- * @return Return the timestamp from the UUIDV8 CloudEvent ID or a Null if timestamp can't be extracted.
- */
- fun getCreationTimestamp(cloudEvent: CloudEvent): Long? {
- val cloudEventId = cloudEvent.id
- val uuid = LongUuidSerializer.INSTANCE.deserialize(cloudEventId)
- return uuid.getTime()
- }
-
- /**
- * Calculate if a CloudEvent configured with a creation time and a ttl attribute is expired.
- * The ttl attribute is a configuration of how long this event should live for after it was generated (in milliseconds)
- * @param cloudEvent The CloudEvent to inspect for being expired.
- * @return Returns true if the CloudEvent was configured with a ttl > 0 and a creation time to compare for expiration.
- */
- fun isExpiredByCloudEventCreationDate(cloudEvent: CloudEvent): Boolean {
- val ttl = getTtl(cloudEvent) ?: return false
- if (ttl <= 0) {
- return false
- }
- val cloudEventCreationTime: OffsetDateTime = cloudEvent.time ?: return false
- val now: OffsetDateTime = OffsetDateTime.now()
- val creationTimePlusTtl: OffsetDateTime = cloudEventCreationTime.plus(ttl.toLong(), ChronoUnit.MILLIS)
- return now.isAfter(creationTimePlusTtl)
- }
-
- /**
- * Calculate if a CloudEvent configured with UUIDv8 id and a ttl attribute is expired.
- * The ttl attribute is a configuration of how long this event should live for after it was generated (in milliseconds)
- * @param cloudEvent The CloudEvent to inspect for being expired.
- * @return Returns true if the CloudEvent was configured with a ttl > 0 and UUIDv8 id to compare for expiration.
- */
- fun isExpired(cloudEvent: CloudEvent): Boolean {
- val ttl = getTtl(cloudEvent) ?: return false
- if (ttl <= 0) {
- return false
- }
- val cloudEventId: String = cloudEvent.id
- val uuid = LongUuidSerializer.INSTANCE.deserialize(cloudEventId)
- if (uuid == UUID.getDefaultInstance()) {
- return false
- }
- val delta: Long = System.currentTimeMillis() - (uuid.getTime() ?: 0L)
- return delta >= ttl
- }
-
- /**
- * Check if a CloudEvent is a valid UUIDv6 or v8 .
- * @param cloudEvent The CloudEvent with the id to inspect.
- * @return Returns true if the CloudEvent is valid.
- */
- fun isCloudEventId(cloudEvent: CloudEvent): Boolean {
- val cloudEventId: String = cloudEvent.id
- val uuid = LongUuidSerializer.INSTANCE.deserialize(cloudEventId)
- return uuid.isUuid()
- }
-
- /**
- * Extract the payload from the CloudEvent as a protobuf Any object.
- * An all or nothing error handling strategy is implemented. If anything goes wrong, an Any.getDefaultInstance() will be returned.
- * @param cloudEvent CloudEvent containing the payload to extract.
- * @return Extracts the payload from a CloudEvent as a Protobuf Any object.
- */
- fun getPayload(cloudEvent: CloudEvent): Any {
- val data: CloudEventData = cloudEvent.data ?: return Any.getDefaultInstance()
- return try {
- Any.parseFrom(data.toBytes())
- } catch (e: InvalidProtocolBufferException) {
- Any.getDefaultInstance()
- }
- }
-
- /**
- * Extract the payload from the CloudEvent as a protobuf Message of the provided class. The protobuf of this message
- * class must be loaded on the client for this to work.
- * An all or nothing error handling strategy is implemented. If anything goes wrong, a Null will be returned.
- * Example:
- *
- * @param cloudEvent CloudEvent containing the payload to extract.
- * @param clazz The class that extends [Message] that the payload is extracted into.
- * @return Returns a [Message] payload of the class type that is provided.
- * @param The class type of the Message to be unpacked.
- */
- fun unpack(cloudEvent: CloudEvent, clazz: Class): T? {
- return try {
- getPayload(cloudEvent).unpack(clazz)
- } catch (e: InvalidProtocolBufferException) {
- // All or nothing error handling strategy. If something goes wrong, you just get an empty.
- null
- }
- }
-
- /**
- * Function used to pretty print a CloudEvent containing only the id, source, type and maybe a sink. Used mainly for logging.
- * @param cloudEvent The CloudEvent we want to pretty print.
- * @return returns the String representation of the CloudEvent containing only the id, source, type and maybe a sink.
- */
- fun toString(cloudEvent: CloudEvent): String {
- val sink = getSink(cloudEvent)?.let { ", sink='$it'" } ?: ""
- return "CloudEvent{id='${cloudEvent.id}', source='${cloudEvent.source}'${sink}, type='${cloudEvent.type}'}"
-
- }
-
- /**
- * Utility for extracting the String value of an extension.
- * @param extensionName The name of the CloudEvent extension.
- * @param cloudEvent The CloudEvent containing the data.
- * @return returns the String value of the extension matching the extension name,
- * or a Null is the value does not exist.
- */
- private fun extractStringValueFromExtension(extensionName: String, cloudEvent: CloudEvent): String? {
- return cloudEvent.extensionNames?.let {
- if (it.contains(extensionName)) {
- cloudEvent.getExtension(extensionName)?.toString()
- } else {
- null
- }
- }
- }
-
- /**
- * Utility for extracting the Integer value of an extension.
- * @param extensionName The name of the CloudEvent extension.
- * @param cloudEvent The CloudEvent containing the data.
- * @return returns the Integer value of the extension matching the extension name,
- * or a Null is the value does not exist.
- */
- private fun extractIntegerValueFromExtension(extensionName: String, cloudEvent: CloudEvent): Int? {
- return extractStringValueFromExtension(extensionName, cloudEvent)?.toInt()
- }
-
- /**
- * Get the string representation of the UMessageType.
- *
- * Note: The UMessageType is determined by the type of the CloudEvent. If
- * the UMessageType is UMESSAGE_TYPE_NOTIFICATION, we assume the CloudEvent type
- * is "pub.v1" and the sink is present.
- * @param type The UMessageType
- * @return returns the string representation of the UMessageType
- *
- */
- fun getEventType(type: UMessageType): String {
- return getCeName(type.valueDescriptor)
- }
-
- /**
- * Get the string representation of the UPriority
- * @param priority
- * @return returns the string representation of the UPriority
- */
- fun getCePriority(priority: UPriority): String {
- return getCeName(priority.valueDescriptor)
- }
-
- /**
- * Get the UPriority from the string name
- * @param priority
- * @return returns the UPriority
- */
- fun getUPriority(priority: String, default : UPriority = UPriority.UNRECOGNIZED): UPriority {
- return UPriority.getDescriptor().values
- .filter { value ->
- value.options.hasExtension(UprotocolOptions.ceName) && value.options
- .getExtension(UprotocolOptions.ceName) == priority
- }.map { value ->
- UPriority.forNumber(value.number)
- }.firstOrNull() ?: default
- }
-
- /**
- * Get the UMessageType from the string representation.
- *
- * Note: The UMessageType is determined by the type of the CloudEvent.
- * If the CloudEvent type is "pub.v1" and the sink is present, the UMessageType is assumed to be
- * UMESSAGE_TYPE_NOTIFICATION, this is because uProtocol CloudEvent definition did not have an explicit
- * notification type.
- *
- * @return returns the UMessageType
- */
- fun getMessageType(type: String): UMessageType {
- return UMessageType.getDescriptor().values
- .filter { value ->
- value.options.hasExtension(UprotocolOptions.ceName) && value.options
- .getExtension(UprotocolOptions.ceName) == type
- }.map { value ->
- UMessageType.forNumber(value.number)
- }.firstOrNull() ?: UMessageType.UNRECOGNIZED
- }
-
- /**
- * Get the UMessage from the cloud event
- * @param event The CloudEvent containing the data.
- * @return returns the UMessage
- */
- fun toMessage(event: CloudEvent): UMessage {
-
- val msgPayload = uPayload {
- format = getUPayloadFormatFromContentType(event.dataContentType)
- value = getPayload(event).toByteString()
- }
-
- val msgAttributes = uAttributes {
- id = LongUuidSerializer.INSTANCE.deserialize(event.id)
- type = getMessageType(event.type)
- source = LongUriSerializer.INSTANCE.deserialize(event.source.toString())
- if (hasCommunicationStatusProblem(event)) {
- commstatus = getCommunicationStatus(event)
- }
- getPriority(event)?.let { p ->
- priority = getUPriority(p, UPriority.UPRIORITY_UNSPECIFIED)
- }
-
- getSink(event)?.let { sink = LongUriSerializer.INSTANCE.deserialize(it.value) }
-
- getRequestId(event)?.let { reqid = LongUuidSerializer.INSTANCE.deserialize(it) }
-
- getTtl(event)?.let { ttl = it }
-
- getToken(event)?.let { token = it }
-
- getTraceparent(event)?.let { traceparent = it }
-
- extractIntegerValueFromExtension("plevel", event)?.let { permissionLevel = it }
-
- }
- return uMessage {
- attributes = msgAttributes
- payload = msgPayload
- }
- }
-
- /**
- * Get the Cloudevent from the UMessage
- * Note: For now, only the value format of UPayload is supported in the SDK.If the UPayload has a reference, it
- * needs to be copied to CloudEvent.
- * @param message The UMessage protobuf containing the data
- * @return returns the cloud event
- */
- fun fromMessage(message: UMessage): CloudEvent {
- val attributes: UAttributes = message.attributes ?: UAttributes.getDefaultInstance()
- val payload = message.payload ?: UPayload.getDefaultInstance()
- val builder: CloudEventBuilder =
- CloudEventBuilder.v1().withId(LongUuidSerializer.INSTANCE.serialize(attributes.id))
- builder.withType(getEventType(attributes.type))
- builder.withSource(URI.create(LongUriSerializer.INSTANCE.serialize(attributes.source)))
- val contentType = getContentTypeFromUPayloadFormat(payload.format)
- if (contentType.isNotEmpty()) {
- builder.withDataContentType(contentType)
- }
- // IMPORTANT: Currently, ONLY the VALUE format is supported in the SDK!
- if (payload.hasValue()) {
- builder.withData(payload.value.toByteArray())
- }
-
- if (attributes.hasTtl()) {
- builder.withExtension("ttl", attributes.ttl)
- }
- if (attributes.hasToken()) {
- builder.withExtension("token", attributes.token)
- }
-
- if (attributes.priorityValue > 0) {
- builder.withExtension("priority", getCePriority(attributes.priority))
- }
-
- if (attributes.hasSink()) {
- builder.withExtension("sink", URI.create(LongUriSerializer.INSTANCE.serialize(attributes.sink)))
- }
-
- if (attributes.hasCommstatus()) {
- builder.withExtension("commstatus", attributes.commstatus.number)
- }
-
- if (attributes.hasReqid()) {
- builder.withExtension("reqid", LongUuidSerializer.INSTANCE.serialize(attributes.reqid))
- }
-
- if (attributes.hasPermissionLevel()) {
- builder.withExtension("plevel", attributes.permissionLevel)
- }
-
- if (attributes.hasTraceparent()) {
- builder.withExtension("traceparent", attributes.traceparent)
- }
-
- return builder.build()
-
- }
-
- /**
- * Retrieves the payload format enumeration based on the provided string representation of the data content type
- * This method uses the uProtocol mimeType custom options declared in upayload.proto.
- *
- * @param contentType The content type string representing the format of the payload.
- * @return The corresponding UPayloadFormat enumeration based on the content type.
- */
- private fun getUPayloadFormatFromContentType(contentType: String?): UPayloadFormat {
- if (contentType == null) {
- return UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY
- }
- return UPayloadFormat.getDescriptor().values.filter { v: EnumValueDescriptor ->
- v.options.hasExtension(UprotocolOptions.mimeType) && v.options
- .getExtension(UprotocolOptions.mimeType) == contentType
- }.map { v: EnumValueDescriptor ->
- UPayloadFormat.forNumber(v.number)
- }.firstOrNull() ?: UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY
- }
-
- /**
- * Retrieves the string representation of the data content type based on the provided UPayloadFormat.
- * This method uses the uProtocol mimeType custom options declared in upayload.proto.
- *
- * @param format The UPayloadFormat enumeration representing the payload format.
- * @return The corresponding content type string based on the payload format.
- */
- fun getContentTypeFromUPayloadFormat(format: UPayloadFormat): String {
- // Since the default value is UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY, we return an empty string.
- if (format == UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY) {
- return ""
- }
- return format.valueDescriptor.options.getExtension(UprotocolOptions.mimeType)
- }
-
- /**
- * Retrieves the string representation of the data content type based on the provided Enum value descriptor.
- *
- * @param descriptor The EnumDescriptor enumeration representing the payload format.
- * @return The corresponding string name for the value.
- */
- fun getCeName(descriptor: EnumValueDescriptor): String {
- return descriptor.options.getExtension(UprotocolOptions.ceName)
- }
-}
-
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/Base64ProtobufSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/Base64ProtobufSerializer.kt
deleted file mode 100644
index caa9b59..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/Base64ProtobufSerializer.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.serialize
-
-import java.util.Base64
-
-/**
- * Helper for serializing Base64 protobuf data.
- */
-object Base64ProtobufSerializer {
- /**
- * Deserialize a base64 protobuf payload into a Base64 String.
- * @param bytes byte[] data
- * @return Returns a String from the base64 protobuf payload.
- */
- fun deserialize(bytes: ByteArray?): String {
- return if (bytes == null) {
- ""
- } else Base64.getEncoder().encodeToString(bytes)
- }
-
- /**
- * Serialize a String into Base64 format.
- * @param stringToSerialize String to serialize.
- * @return Returns the Base64 formatted String as a byte[].
- */
- fun serialize(stringToSerialize: String?): ByteArray {
- return if (stringToSerialize == null) {
- ByteArray(0)
- } else Base64.getDecoder().decode(stringToSerialize.toByteArray())
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventSerializer.kt
deleted file mode 100644
index 6bf03c4..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventSerializer.kt
+++ /dev/null
@@ -1,32 +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.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.serialize
-
-import io.cloudevents.CloudEvent
-
-interface CloudEventSerializer {
- fun serialize(cloudEvent: CloudEvent): ByteArray
- fun deserialize(bytes: ByteArray): CloudEvent
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventSerializers.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventSerializers.kt
deleted file mode 100644
index 1b7cdbd..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventSerializers.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.serialize
-
-/**
- * Provides Singleton instances of the CloudEvent Serializers.
- */
-enum class CloudEventSerializers(private val cloudEventSerializer: CloudEventSerializer) {
- JSON(CloudEventToJsonSerializer()),
- PROTOBUF(CloudEventToProtobufSerializer());
-
- fun serializer(): CloudEventSerializer {
- return cloudEventSerializer
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializer.kt
deleted file mode 100644
index 8f0299a..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializer.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.serialize
-
-import io.cloudevents.CloudEvent
-import io.cloudevents.jackson.JsonFormat
-
-/**
- * CloudEventSerializer to serialize and deserialize CloudEvents to JSON format.
- */
-class CloudEventToJsonSerializer : CloudEventSerializer {
- override fun serialize(cloudEvent: CloudEvent): ByteArray {
- return serializer.serialize(cloudEvent)
- }
-
- override fun deserialize(bytes: ByteArray): CloudEvent {
- return serializer.deserialize(bytes)
- }
-
- companion object {
- // Force database64 encoding as we know the data will be in a protobuf format
- private val serializer: JsonFormat = JsonFormat(true, false)
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializer.kt
deleted file mode 100644
index 68ffd10..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializer.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.serialize
-
-import io.cloudevents.CloudEvent
-import io.cloudevents.protobuf.ProtobufFormat
-
-/**
- * CloudEventSerializer to serialize and deserialize CloudEvents to protobuf format.
- */
-class CloudEventToProtobufSerializer : CloudEventSerializer {
- override fun serialize(cloudEvent: CloudEvent): ByteArray {
- return serializer.serialize(cloudEvent)
- }
-
- override fun deserialize(bytes: ByteArray): CloudEvent {
- return serializer.deserialize(bytes)
- }
-
- companion object {
- private val serializer: ProtobufFormat = ProtobufFormat()
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.kt b/src/main/kotlin/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.kt
deleted file mode 100644
index 37459b1..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidator.kt
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.cloudevent.validate
-
-import io.cloudevents.CloudEvent
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uri.toUri
-import org.eclipse.uprotocol.uri.validator.isRpcMethod
-import org.eclipse.uprotocol.uri.validator.validate
-import org.eclipse.uprotocol.v1.*
-import org.eclipse.uprotocol.validation.ValidationResult
-
-/**
- * Validates a CloudEvent using google.grpc.Status
- *
- * [google.grpc.Status](https://grpc.github.io/grpc/core/md_doc_statuscodes.html)
- */
-sealed class CloudEventValidator {
- protected abstract val typeName: String
-
- //hardcode to prevent obfuscation
- protected abstract val className: String
-
- /**
- * Validate the CloudEvent. A CloudEventValidator instance is obtained according to the type attribute on the CloudEvent.
- * @param cloudEvent The CloudEvent to validate.
- * @return Returns a UStatus with success or a UUStatus with failure containing all the errors that were found.
- */
- fun validate(cloudEvent: CloudEvent): ValidationResult {
- val errorMessage = listOf(
- validateVersion(cloudEvent),
- validateId(cloudEvent),
- validateSource(cloudEvent),
- validateType(cloudEvent),
- validateSink(cloudEvent)
- ).filter { it.isFailure() }.joinToString(",") { it.getMessage() }
- return if (errorMessage.isBlank()) {
- ValidationResult.success()
- } else {
- ValidationResult.failure(errorMessage)
-
- }
- }
-
-
- /**
- * Validate the source value of a cloud event.
- * @param cloudEvent The cloud event containing the source to validate.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- abstract fun validateSource(cloudEvent: CloudEvent): ValidationResult
-
- /**
- * Validate the type of a cloud event.
- * @param cloudEvent The cloud event containing the source to validate.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun validateType(cloudEvent: CloudEvent): ValidationResult {
- return if ("$typeName.v1" == cloudEvent.type) ValidationResult.success() else ValidationResult.failure(
- "Invalid CloudEvent type [${cloudEvent.type}]. CloudEvent of type $className must have a type of '$typeName.v1'"
- )
- }
-
- override fun toString(): String {
- return "CloudEventValidator.$className"
- }
-
- /**
- * Validate the sink value of a cloud event in the default scenario where the sink attribute is optional.
- * @param cloudEvent The cloud event containing the sink to validate.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- open fun validateSink(cloudEvent: CloudEvent): ValidationResult {
- return UCloudEvent.getSink(cloudEvent)?.let { sink ->
- val checkSink = sink.validateUEntityUri()
- if (checkSink.isFailure()) {
- ValidationResult.failure("Invalid CloudEvent sink [${sink}]. ${checkSink.getMessage()}")
- } else {
- ValidationResult.success()
- }
- } ?: ValidationResult.success()
- }
-
- companion object {
- /**
- * Obtain a CloudEventValidator according to the type attribute in the CloudEvent.
- * @return Returns a CloudEventValidator according to the type attribute in the CloudEvent.
- */
- fun CloudEvent.getValidator(): CloudEventValidator {
- val cloudEventType: String? = type
- if (cloudEventType.isNullOrEmpty()) {
- return Publish
- }
- val validator: CloudEventValidator = when (UCloudEvent.getMessageType(cloudEventType)) {
- UMessageType.UMESSAGE_TYPE_NOTIFICATION -> Notification
- UMessageType.UMESSAGE_TYPE_RESPONSE -> Response
- UMessageType.UMESSAGE_TYPE_REQUEST -> Request
- else -> Publish
- }
- return validator
- }
-
- fun validateVersion(cloudEvent: CloudEvent): ValidationResult {
- return validateVersion(cloudEvent.specVersion.toString())
- }
-
- fun validateId(cloudEvent: CloudEvent): ValidationResult {
- return if (UCloudEvent.isCloudEventId(cloudEvent)) ValidationResult.success() else ValidationResult.failure(
- "Invalid CloudEvent Id [${cloudEvent.id}]. CloudEvent Id must be of type UUIDv8."
- )
- }
-
- /**
- * Validate an UriPart for a Software Entity must have an authority in the case of a microRemote uri, and must contain
- * the name of the USE.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun Uri.validateUEntityUri(): ValidationResult {
- return LongUriSerializer.INSTANCE.deserialize(this.value).validateUEntityUri()
- }
-
- /**
- * Validate an UriPart for a Software Entity must have an authority in the case of a microRemote uri, and must contain
- * the name of the USE.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun UUri.validateUEntityUri(): ValidationResult {
- return validate()
- }
-
- fun validateVersion(version: String): ValidationResult {
- return if (version == "1.0") ValidationResult.success() else ValidationResult.failure(
- "Invalid CloudEvent version [$version]. CloudEvent version must be 1.0."
- )
- }
-
- /**
- * Validate a UriPart that is to be used as a topic in publish scenarios for events such as publish, file and notification.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun Uri.validateTopicUri(): ValidationResult {
- return LongUriSerializer.INSTANCE.deserialize(this.value).validateTopicUri()
- }
-
- /**
- * Validate a UriPart that is to be used as a topic in publish scenarios for events such as publish, file and notification.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun UUri.validateTopicUri(): ValidationResult {
- val validationResult: ValidationResult = validateUEntityUri()
- if (validationResult.isFailure()) {
- return validationResult
- }
- val uResource: UResource = resource
- if (uResource.name.isBlank()) {
- return ValidationResult.failure("UriPart is missing uResource name.")
- }
- return if (uResource.message.isEmpty()) {
- ValidationResult.failure("UriPart is missing Message information.")
- } else ValidationResult.success()
- }
-
- /**
- * 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.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun Uri.validateRpcTopicUri(): ValidationResult {
- return LongUriSerializer.INSTANCE.deserialize(this.value).validateRpcTopicUri()
- }
-
- /**
- * Validate an UriPart that is meant to be used as the application response topic for rpc calls.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun UUri.validateRpcTopicUri(): ValidationResult {
- val validationResult: ValidationResult = validateUEntityUri()
- if (validationResult.isFailure()) {
- return ValidationResult.failure("Invalid RPC uri application response topic. ${validationResult.getMessage()}")
- }
- val uResource: UResource = resource
- val topic = "${uResource.name}.${uResource.instance}"
- return if ("rpc.response" != topic) {
- ValidationResult.failure("Invalid RPC uri application response topic. UriPart is missing rpc.response.")
- } else ValidationResult.success()
- }
-
- /**
- * Validate a UriPart that is meant to be used as an RPC method URI. Used in Request sink values and Response source values.
- * @return Returns the ValidationResult containing a success or a failure with the error message.
- */
- fun Uri.validateRpcMethod(): ValidationResult {
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(this.value)
- val validationResult: ValidationResult = uuri.validateUEntityUri()
- if (validationResult.isFailure()) {
- return ValidationResult.failure("Invalid RPC method uri. ${validationResult.getMessage()}")
- }
- return if (!uuri.isRpcMethod()) {
- ValidationResult.failure("Invalid RPC method uri. UriPart should be the method to be called, or method from response.")
- } else ValidationResult.success()
- }
- }
-}
-
-/**
- * Implements Validations for a CloudEvent of type Publish.
- */
-object Publish : CloudEventValidator() {
- override val typeName: String = "pub"
- override val className: String = "Publish"
-
- override fun validateSource(cloudEvent: CloudEvent): ValidationResult {
- val source: Uri = cloudEvent.source.toString().toUri()
- val checkSource = source.validateTopicUri()
- return if (checkSource.isFailure()) {
- ValidationResult.failure(
- "Invalid Publish type CloudEvent source [${source}]. ${checkSource.getMessage()}"
- )
- } else ValidationResult.success()
- }
-}
-
-/**
- * Implements Validations for a CloudEvent of type Publish that behaves as a Notification, meaning
- * it must have a sink.
- */
-object Notification : CloudEventValidator() {
- override val typeName: String = "not"
- override val className: String = "Notification"
- override fun validateSource(cloudEvent: CloudEvent): ValidationResult {
- val source: Uri = cloudEvent.source.toString().toUri()
- val checkSource = source.validateTopicUri()
- return if (checkSource.isFailure()) {
- ValidationResult.failure(
- "Invalid Notification type CloudEvent source [${source}]. ${checkSource.getMessage()}"
- )
- } else ValidationResult.success()
- }
-
- override fun validateSink(cloudEvent: CloudEvent): ValidationResult {
- val sink = UCloudEvent.getSink(cloudEvent)
- ?: return ValidationResult.failure("Invalid CloudEvent sink. Notification CloudEvent sink must be an uri.")
- val checkSink: ValidationResult = sink.validateUEntityUri()
- if (checkSink.isFailure()) {
- return ValidationResult.failure(
- "Invalid Notification type CloudEvent sink [${sink}]. ${checkSink.getMessage()}"
- )
- }
- return ValidationResult.success()
- }
-}
-
-/**
- * Implements Validations for a CloudEvent for RPC Request.
- */
-object Request : CloudEventValidator() {
- override val typeName: String = "req"
- override val className: String = "Request"
-
- override fun validateSource(cloudEvent: CloudEvent): ValidationResult {
- val source = cloudEvent.source.toString().toUri()
- val checkSource: ValidationResult = source.validateRpcTopicUri()
- return if (checkSource.isFailure()) {
- ValidationResult.failure(
- "Invalid RPC Request CloudEvent source [${source}]. ${checkSource.getMessage()}"
- )
- } else ValidationResult.success()
- }
-
-
- override fun validateSink(cloudEvent: CloudEvent): ValidationResult {
- val sink = UCloudEvent.getSink(cloudEvent)
- ?: return ValidationResult.failure("Invalid RPC Request CloudEvent sink. Request CloudEvent sink must be uri for the method to be called.")
- val checkSink: ValidationResult = sink.validateRpcMethod()
- if (checkSink.isFailure()) {
- return ValidationResult.failure("Invalid RPC Request CloudEvent sink [${sink}]. ${checkSink.getMessage()}")
- }
- return ValidationResult.success()
- }
-}
-
-/**
- * Implements Validations for a CloudEvent for RPC Response.
- */
-object Response : CloudEventValidator() {
- override val typeName: String = "res"
- override val className: String = "Response"
-
- override fun validateSource(cloudEvent: CloudEvent): ValidationResult {
- val source = cloudEvent.source.toString().toUri()
- val checkSource: ValidationResult = source.validateRpcMethod()
- return if (checkSource.isFailure()) {
- ValidationResult.failure(
- "Invalid RPC Response CloudEvent source [$source]. ${checkSource.getMessage()}"
- )
- } else ValidationResult.success()
- }
-
- override fun validateSink(cloudEvent: CloudEvent): ValidationResult {
- val sink = UCloudEvent.getSink(cloudEvent)
- ?: return ValidationResult.failure("Invalid CloudEvent sink. Response CloudEvent sink must be uri the destination of the response.")
- val checkSink: ValidationResult = sink.validateRpcTopicUri()
- if (checkSink.isFailure()) {
- return ValidationResult.failure(
- "Invalid RPC Response CloudEvent sink [$sink]. ${checkSink.getMessage()}"
- )
- }
- return ValidationResult.success()
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/rpc/README.adoc b/src/main/kotlin/org/eclipse/uprotocol/rpc/README.adoc
deleted file mode 100644
index eb3a6cb..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/rpc/README.adoc
+++ /dev/null
@@ -1,8 +0,0 @@
-= uProtocol Rpc Interfaces
-:toc:
-:sectnums:
-
-== Overview
-
-The following module declares the https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l2/rpcclient.adoc[RpcClient interface] defined in uProtocol specification. The interface is used by code generators to build client and service stubs for uServices.
-
diff --git a/src/main/kotlin/org/eclipse/uprotocol/rpc/RpcClient.kt b/src/main/kotlin/org/eclipse/uprotocol/rpc/RpcClient.kt
deleted file mode 100644
index c39e617..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/rpc/RpcClient.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.rpc
-
-import kotlinx.coroutines.flow.Flow
-import org.eclipse.uprotocol.v1.CallOptions
-import org.eclipse.uprotocol.v1.UPayload
-import org.eclipse.uprotocol.v1.UMessage
-import org.eclipse.uprotocol.v1.UUri
-
-/**
- * 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 mapping a RPC request to a response. 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]
- */
-interface RpcClient {
- /**
- * API for clients to invoke a method (send an RPC request) and receive the response (the returned
- * {@link CompletionStage} {@link UPayload}.
- * Client will set method to be the URI of the method they want to invoke,
- * payload to the request message, and attributes with the various metadata for the
- * method invocation.
- * @param methodUri The method URI to be invoked, ex (long form): /example.hello_world/1/rpc.SayHello.
- * @param requestPayload The request message to be sent to the server.
- * @param options RPC method invocation call options, see {@link CallOptions}
- * @return Returns the Flow with the response message or exception with the failure
- * reason as {@link UStatus}.
- */
- fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/rpc/RpcMapper.kt b/src/main/kotlin/org/eclipse/uprotocol/rpc/RpcMapper.kt
deleted file mode 100644
index f5e8008..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/rpc/RpcMapper.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.rpc
-
-import com.google.protobuf.Any
-import com.google.protobuf.InvalidProtocolBufferException
-import com.google.protobuf.Message
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.map
-import org.eclipse.uprotocol.v1.UCode
-import org.eclipse.uprotocol.v1.UMessage
-import org.eclipse.uprotocol.v1.UStatus
-import java.util.concurrent.CompletionException
-
-/**
- * Inline function to map Flow<UMessage> from Link into a Flow containing the declared expected return type
- * of the RPC method or throw an exception.
- * @return Returns Flow containing the declared expected return type of the RPC method.
- * @param The declared expected return type of the RPC method.
- */
-inline fun Flow.toResponse(): Flow {
- return catch { exception ->
- throw CompletionException(exception.message, exception)
- }.map { message ->
- if (!message.hasPayload()) {
- throw RuntimeException("Server returned a null payload. Expected [${T::class.java.name}]")
- }
- try {
- val any = Any.parseFrom(message.payload.value)
- if (any.`is`(T::class.java)) {
- any.unpack(T::class.java)
- } else {
- throw RuntimeException("Unknown payload type [${any.typeUrl}]. Expected [${T::class.java.name}]")
- }
- } catch (e: InvalidProtocolBufferException) {
- throw RuntimeException("${e.message} [${UStatus::class.java.name}]", e)
- }
- }
-}
-
-/**
- * Map a response of Flow<Any> from Link into a Flow containing a Result containing
- * the declared expected return type T.
- * @return Returns a Flow containing an Result containing the declared expected return type T, if T is UStatus
- * and has code not equals to OK, failure Result will be emitted.
- * @param The declared expected return type of the RPC method.
- */
-inline fun Flow.toResult(): Flow> {
- return toResponse().map { response ->
- response.runCatching {
- if (this is UStatus && code != UCode.OK) {
- throw IllegalStateException("${message}, UStatus: $code")
- } else {
- this
- }
- }
- }.catch {
- emit(Result.failure(it))
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/transport/README.adoc b/src/main/kotlin/org/eclipse/uprotocol/transport/README.adoc
index e154d5d..54fbf83 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/transport/README.adoc
+++ b/src/main/kotlin/org/eclipse/uprotocol/transport/README.adoc
@@ -4,4 +4,36 @@
: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...).
+The following section implements https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/README.adoc[uP-L1 Transport Layer Specifications]. The purpose of the transport layer is to wrap communication middlewares into a common interface that allows us to send and receive any kind of uProtocol messages (publish, request, response, notification) over any kind of transport (HTTP, MQTT, WebSockets, etc).
+
+the datamodel is declared in the uProtocol specifications project in https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/README.adoc[up-core-api] folder and this project declares the language specific transport interface (UListener & UTransport) and the builders, serializers, and validators, for the up-core-api data model. .
+
+Below are the list of the classes and interfaces that are part of the uProtocol Transport Interface & Data Model:
+
+.Transport Interfaces
+[table-transport-interfaces, cols="1,3"]
+|===
+| Class/Interface | Description
+
+| xref:UTransport.kt[*`UTransport`*]
+| Interface that defines the methods that a transport middleware must implement in order to be used by the uProtocol library.
+
+| xref:UListener.kt[*`UListener`*]
+| Callback/listener interface to be able to receive messages from a transport.
+
+| xref:UMessageKtExt.kt[*`UMessageKtExt`*]
+| Kotlin Dsl to build request, response, publish and notification UMessage, and set functions to set attributes.
+
+| xref:validator/UAttributesValidator.kt[*`UAttributesValidator`*]
+| uProtocol Attributes validator that ensures that the publish, notification, request, and response messages are built with the correct information.
+
+|===
+
+== Examples
+
+In the following section we will provide an example for how a transport implementations are expected to implement the uTransport library
+
+[source,java]
+----
+// include::../../../../../../test/java/org/eclipse/uprotocol/communication/TestUTransport.java[]
+----
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/v1/UAttributesKtExt.kt b/src/main/kotlin/org/eclipse/uprotocol/transport/UAttributesKtExt.kt
similarity index 64%
rename from src/main/kotlin/org/eclipse/uprotocol/v1/UAttributesKtExt.kt
rename to src/main/kotlin/org/eclipse/uprotocol/transport/UAttributesKtExt.kt
index 0a84a73..dcec8a6 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/v1/UAttributesKtExt.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/transport/UAttributesKtExt.kt
@@ -1,39 +1,30 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
-package org.eclipse.uprotocol.v1
+package org.eclipse.uprotocol.transport
import org.eclipse.uprotocol.uuid.factory.UUIDV8
+import org.eclipse.uprotocol.v1.*
+
/**
- * Construct a UAttributesBuilder for a publish message.
+ * Construct a UMessageBuilder for a Publish message.
* @param source Source address of the message.
* @param priority The priority of the message.
* @return Returns the UAttributesBuilder with the configured source and priority.
*/
@JvmSynthetic
-fun UAttributesKt.Dsl.forPublication(source: UUri, priority: UPriority) {
+internal fun UAttributesKt.Dsl.forPublication(source: UUri, priority: UPriority) {
this@forPublication.source = source
this@forPublication.priority = priority
id = UUIDV8()
@@ -48,7 +39,7 @@ fun UAttributesKt.Dsl.forPublication(source: UUri, priority: UPriority) {
* @return Returns the UAttributesBuilder with the configured source, sink and priority.
*/
@JvmSynthetic
-fun UAttributesKt.Dsl.forNotification(source: UUri, sink: UUri, priority: UPriority) {
+internal fun UAttributesKt.Dsl.forNotification(source: UUri, sink: UUri, priority: UPriority) {
this@forNotification.source = source
this@forNotification.sink = sink
this@forNotification.priority = priority
@@ -65,7 +56,7 @@ fun UAttributesKt.Dsl.forNotification(source: UUri, sink: UUri, priority: UPrior
* @return Returns the UAttributesBuilder with the configured source, sink, priority and ttl.
*/
@JvmSynthetic
-fun UAttributesKt.Dsl.forRequest(source: UUri, sink: UUri, priority: UPriority, ttl: Int) {
+internal fun UAttributesKt.Dsl.forRequest(source: UUri, sink: UUri, priority: UPriority, ttl: Int) {
this@forRequest.source = source
this@forRequest.sink = sink
this@forRequest.priority = priority
@@ -83,7 +74,7 @@ fun UAttributesKt.Dsl.forRequest(source: UUri, sink: UUri, priority: UPriority,
* @return Returns the UAttributesBuilder with the configured source, sink, priority and reqid.
*/
@JvmSynthetic
-fun UAttributesKt.Dsl.forResponse(source: UUri, sink: UUri, priority: UPriority, reqId: UUID) {
+internal fun UAttributesKt.Dsl.forResponse(source: UUri, sink: UUri, priority: UPriority, reqId: UUID) {
this@forResponse.source = source
this@forResponse.sink = sink
this@forResponse.priority = priority
@@ -98,7 +89,7 @@ fun UAttributesKt.Dsl.forResponse(source: UUri, sink: UUri, priority: UPriority,
* @return Returns the UAttributesBuilder with the configured source, sink, priority and reqid.
*/
@JvmSynthetic
-fun UAttributesKt.Dsl.forResponse(request: UAttributes) {
+internal fun UAttributesKt.Dsl.forResponse(request: UAttributes) {
source = request.sink
sink = request.source
priority = request.priority
diff --git a/src/main/kotlin/org/eclipse/uprotocol/transport/UListener.kt b/src/main/kotlin/org/eclipse/uprotocol/transport/UListener.kt
index 12132ea..f68c074 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/transport/UListener.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/transport/UListener.kt
@@ -1,24 +1,13 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
@@ -28,11 +17,13 @@ import org.eclipse.uprotocol.v1.UMessage
/**
- * For any implementation that defines some kind of callback or function that will be called to handle incoming messages.
+ * For any implementation that defines some kind of callback or function that
+ * will be called to handle incoming messages.
*/
interface UListener {
/**
* Method called to handle/process messages.
+ *
* @param message Message received.
* @return Returns an Ack every time a message is received and processed.
*/
diff --git a/src/main/kotlin/org/eclipse/uprotocol/transport/UMessageKtExt.kt b/src/main/kotlin/org/eclipse/uprotocol/transport/UMessageKtExt.kt
new file mode 100644
index 0000000..648d473
--- /dev/null
+++ b/src/main/kotlin/org/eclipse/uprotocol/transport/UMessageKtExt.kt
@@ -0,0 +1,207 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.transport
+
+import com.google.protobuf.Any
+import com.google.protobuf.ByteString
+import com.google.protobuf.Message
+import org.eclipse.uprotocol.v1.*
+
+/**
+ * Set the Priority of a UMessage. The priority should be at least CS4 for request and response messages,
+ * and CS1 for other messages, incorrect priority will be ignored.
+ * @param priority The priority of the message.
+ *
+ * @return Returns the UMessage with the configured priority.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setPriority(priority: UPriority) {
+ val basePriority = when (attributes.type) {
+ UMessageType.UMESSAGE_TYPE_REQUEST,
+ UMessageType.UMESSAGE_TYPE_RESPONSE -> UPriority.UPRIORITY_CS4
+ else -> UPriority.UPRIORITY_CS1
+ }
+ if (priority.number>= basePriority.number){
+ attributes = attributes.copy { this.priority = priority }
+ }
+}
+
+/**
+ * Set the Permission Level of a UMessage.
+ * @param permissionLevel The permission level of the message.
+ *
+ * @return Returns the UMessage with the configured Permission Level.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setPermissionLevel(permissionLevel: Int) {
+ attributes = attributes.copy { this.permissionLevel = permissionLevel }
+}
+
+/**
+ * Set the ttl of a UMessage.
+ * @param ttl The time-to-live of the message.
+ *
+ * @return Returns the UMessage with the configured ttl.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setTtl(ttl: Int) {
+ attributes = attributes.copy { this.ttl = ttl }
+}
+
+/**
+ * Set the commstatus of a UMessage.
+ * @param commstatus The Communication Status of the message.
+ *
+ * @return Returns the UMessage with the configured commstatus.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setCommStatus(commstatus: UCode) {
+ attributes = attributes.copy { this.commstatus = commstatus }
+}
+
+/**
+ * Set the reqid of a UMessage.
+ * @param reqid The Required ID of the message.
+ *
+ * @return Returns the UMessage with the configured reqid.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setReqid(reqid: UUID) {
+ attributes = attributes.copy { this.reqid = reqid }
+}
+
+/**
+ * Set the token of a UMessage.
+ * @param token The token of the message.
+ *
+ * @return Returns the UMessage with the configured token.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setToken(token: String) {
+ attributes = attributes.copy { this.token = token }
+}
+
+/**
+ * Set the traceparent of a UMessage.
+ * @param traceparent The traceparent of the message.
+ *
+ * @return Returns the UMessage with the configured traceparent.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setTraceparent(traceparent: String) {
+ attributes = attributes.copy { this.traceparent = traceparent }
+}
+
+/**
+ * Set payload and payload format for a UMessage.
+ * @param message Google protobuf message to be packed into the payload
+ *
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setPayload(message: Message) {
+ payload = message.toByteString()
+ attributes = attributes.copy { payloadFormat = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF }
+}
+
+/**
+ * Set payload and payload format for a UMessage.
+ * @param any Google protobuf Any message to be packed into the payload
+ *
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setPayload(any: Any) {
+ payload = any.toByteString()
+ attributes = attributes.copy { payloadFormat = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY }
+}
+
+/**
+ * Set payload and payload format for a UMessage.
+ * @param format The format of the payload.
+ * @param payload The payload of the message.
+ *
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.setPayload(format: UPayloadFormat, payload: ByteString) {
+ this.payload = payload
+ attributes = attributes.copy { payloadFormat = format }
+}
+
+/**
+ * Construct a UMessageBuilder for a publish message.
+ * @param source The topic the message is published to (a.k.a. Source address).
+ *
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.forPublication(source: UUri) {
+ attributes = uAttributes {
+ forPublication(source, UPriority.UPRIORITY_CS1)
+ }
+}
+
+/**
+ * Construct a UMessageBuilder for a notification message.
+ * @param source The topic the message is published to (a.k.a. Source address).
+ * @param sink The destination of the client that send the request.
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.forNotification(source: UUri, sink: UUri) {
+ attributes = uAttributes {
+ forNotification(source, sink, UPriority.UPRIORITY_CS1)
+ }
+}
+
+/**
+ * Construct a UMessageBuilder for a request message.
+ * @param source Source address for the message (address of the client sending the request message).
+ * @param sink The method that is being requested (a.k.a. destination address).
+ * @param ttl The time to live in milliseconds.
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.forRequest(source: UUri, sink: UUri, ttl: Int) {
+ attributes = uAttributes {
+ forRequest(source, sink, UPriority.UPRIORITY_CS4, ttl)
+ }
+}
+
+/**
+ * Construct a UMessageBuilder for a response message.
+ * @param source The source address of the method that was requested
+ * @param sink The destination of the client that send the request.
+ * @param reqId The original request UUID used to correlate the response to the request.
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.forResponse(source: UUri, sink: UUri, reqId: UUID) {
+ attributes = uAttributes {
+ forResponse(source, sink, UPriority.UPRIORITY_CS4, reqId)
+ }
+}
+
+/**
+ * Construct a UMessageBuilder for a response message.
+ * @param request The request message that was received.
+ * @return Returns the UMessage with the configured payload.
+ */
+@JvmSynthetic
+fun UMessageKt.Dsl.forResponse(request: UAttributes) {
+ attributes = uAttributes {
+ forResponse(request)
+ }
+}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/transport/UPayloadExt.kt b/src/main/kotlin/org/eclipse/uprotocol/transport/UPayloadExt.kt
deleted file mode 100644
index 637183c..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/transport/UPayloadExt.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.eclipse.uprotocol.transport
-
-import com.google.protobuf.Any
-import com.google.protobuf.Internal
-import com.google.protobuf.InvalidProtocolBufferException
-import com.google.protobuf.Message
-import org.eclipse.uprotocol.v1.UPayload
-import org.eclipse.uprotocol.v1.UPayloadFormat
-
-
-/**
- * Unpack a uPayload into a google.protobuf.Message.
- *
- * @param payload the payload to unpack
- * @param clazz the class of the message to unpack
- * @return the unpacked message
- */
-@Suppress("UNCHECKED_CAST")
-fun unpack(payload: UPayload, clazz: Class): T? {
- if (!payload.hasValue()) {
- return null
- }
- return try {
- when (payload.format) {
- UPayloadFormat.UPAYLOAD_FORMAT_UNSPECIFIED, UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY -> {
- Any.parseFrom(payload.value).unpack(clazz)
- }
-
- UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF -> {
- val defaultInstance = Internal.getDefaultInstance(clazz)
- defaultInstance.parserForType.parseFrom(payload.value) as T
- }
-
- else -> null
- }
- } catch (e: InvalidProtocolBufferException) {
- null
- }
-}
-
-/**
- * Inline function to unpack a uPayload into a google.protobuf.Message.
- *
- * @return the unpacked message
- */
-inline fun UPayload.unpack(): T? {
- return unpack(this, T::class.java)
-}
-
diff --git a/src/main/kotlin/org/eclipse/uprotocol/transport/UTransport.kt b/src/main/kotlin/org/eclipse/uprotocol/transport/UTransport.kt
index 6804169..2f81125 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/transport/UTransport.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/transport/UTransport.kt
@@ -1,24 +1,13 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
@@ -37,7 +26,6 @@ import org.eclipse.uprotocol.v1.UUri
* https://github.com/eclipse-uprotocol/up-spec/blob/main/up-l1/README.adoc.
*/
interface UTransport {
-
/**
* Send a message over the transport.
* @param message the [UMessage] to be sent.
@@ -46,23 +34,34 @@ interface UTransport {
fun send(message: UMessage): UStatus
/**
- * Register `UListener` for `UUri` topic to be called when a message is received.
- * @param topic `UUri` to listen for messages from.
- * @param listener The `UListener` that will be executed when the message is
+ * Register `UListener` for `UUri` source and sink filters to be called when a message is received.
+ *
+ * @param sourceFilter The UAttributes::source address pattern that the message to receive needs to match.
+ * @param sinkFilter The UAttributes::sink address pattern that the message to receive needs to match.
+ * @param listener The [UListener] that will be executed when the message is
* received on the given `UUri`.
* @return Returns [UStatus] with [UCode.OK] if the listener is registered
- * correctly, otherwise it returns with dthe appropriate failure.
+ * correctly, otherwise it returns with the appropriate failure.
*/
- fun registerListener(topic: UUri, listener: UListener): UStatus
+ fun registerListener(sourceFilter: UUri, sinkFilter: UUri? = null, listener: UListener): UStatus
/**
- * Unregister `UListener` for `UUri` topic. Messages arriving on this topic will
+ * Unregister `UListener` for `UUri` source and sink filters. Messages arriving on this topic will
* no longer be processed by this listener.
- * @param topic `UUri` to the listener was registered for.
- * @param listener The `UListener` that will no longer want to be registered to receive
+ *
+ * @param sourceFilter The UAttributes::source address pattern that the message to receive needs to match.
+ * @param sinkFilter The UAttributes::sink address pattern that the message to receive needs to match.
+ * @param listener The [UListener] that will no longer want to be registered to receive
* messages.
* @return Returns [UStatus] with [UCode.OK] if the listener is unregistered
* correctly, otherwise it returns with the appropriate failure.
*/
- fun unregisterListener(topic: UUri, listener: UListener): UStatus
+ fun unregisterListener(sourceFilter: UUri, sinkFilter: UUri? = null, listener: UListener): UStatus
+
+ /**
+ * Return the source address for the uE (authority, entity, and resource information)
+ *
+ * @return [UUri] containing the source address
+ */
+ fun getSource(): UUri
}
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/transport/validate/UAttributesValidator.kt b/src/main/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidator.kt
similarity index 76%
rename from src/main/kotlin/org/eclipse/uprotocol/transport/validate/UAttributesValidator.kt
rename to src/main/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidator.kt
index e168cc6..916ba20 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/transport/validate/UAttributesValidator.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidator.kt
@@ -1,32 +1,21 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
-package org.eclipse.uprotocol.transport.validate
+package org.eclipse.uprotocol.transport.validator
-import org.eclipse.uprotocol.uri.validator.validate
-import org.eclipse.uprotocol.uri.validator.validateRpcMethod
-import org.eclipse.uprotocol.uri.validator.validateRpcResponse
+import org.eclipse.uprotocol.uri.validator.isDefaultResourceId
+import org.eclipse.uprotocol.uri.validator.isRpcMethod
+import org.eclipse.uprotocol.uri.validator.isRpcResponse
import org.eclipse.uprotocol.uuid.factory.getTime
import org.eclipse.uprotocol.uuid.factory.isUuid
import org.eclipse.uprotocol.v1.*
@@ -34,12 +23,15 @@ import org.eclipse.uprotocol.validation.ValidationResult
/**
- * [UAttributes] is the class that defines the Payload. It is the place for configuring time to live, priority,
+ * [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
+ * 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
+ * UAttributesValidator is a base class for all UAttribute validators, that can
+ * help validate that the
* [UAttributes] object is correctly defined
* to define the Payload correctly.
*/
@@ -47,6 +39,7 @@ sealed class UAttributesValidator {
//hardcode to prevent obfuscation
protected abstract val className: String
protected abstract val type: UMessageType
+
/**
* Take a [UAttributes] object and run validations.
*
@@ -59,7 +52,7 @@ sealed class UAttributesValidator {
val errorMessage = listOf(
validateType(attributes),
validateTtl(attributes), validateSink(attributes), validatePriority(attributes),
- validatePermissionLevel(attributes), validateReqId(attributes)
+ validatePermissionLevel(attributes), validateReqId(attributes), validateId(attributes)
).filter {
it.isFailure()
}.joinToString(",") { obj -> obj.getMessage() }
@@ -104,19 +97,12 @@ sealed class UAttributesValidator {
}
/**
- * Validate the sink UriPart for the default case. If the UAttributes does not contain a sink then the
- * ValidationResult is ok.
+ * Validate the sink UriPart.
*
* @param attributes UAttributes object containing the sink to validate.
* @return Returns a [ValidationResult] that is success or failed with a failure message.
*/
- open fun validateSink(attributes: UAttributes): ValidationResult {
- return if (attributes.hasSink()) {
- attributes.sink.validate()
- } else {
- ValidationResult.success()
- }
- }
+ abstract fun validateSink(attributes: UAttributes): ValidationResult
/**
* Validate the permissionLevel for the default case. If the UAttributes does not contain a permission level then
@@ -134,15 +120,15 @@ sealed class UAttributesValidator {
}
/**
- * Validate the correlationId for the default case. If the UAttributes does not contain a request id then the
- * ValidationResult is ok.
+ * Validate the correlationId for the default case. Only the response message should have a reqid.
*
* @param attributes Attributes object containing the request id to validate.
- * @return Returns a [ValidationResult] that is success or failed with a failure message.
+ * @return Returns a [ValidationResult] that is success or failed with a
+ * failure message.
*/
open fun validateReqId(attributes: UAttributes): ValidationResult {
- return if (attributes.hasReqid() && !attributes.reqid.isUuid()) {
- ValidationResult.failure("Invalid UUID")
+ return if (attributes.hasReqid()) {
+ ValidationResult.failure("Message should not have a reqid")
} else {
ValidationResult.success()
}
@@ -155,13 +141,32 @@ sealed class UAttributesValidator {
* @return Returns a [ValidationResult] that is success or failed with a failure message.
*/
open fun validatePriority(attributes: UAttributes): ValidationResult {
- return if (attributes.priority.number >= UPriority.UPRIORITY_CS0_VALUE) {
+ return if (attributes.priority.number >= UPriority.UPRIORITY_CS1_VALUE) {
ValidationResult.success()
} else {
ValidationResult.failure("Invalid UPriority [${attributes.priority.name}]")
}
}
+ /**
+ * Validate the Id for the default case. If the UAttributes object does not
+ * contain an Id,
+ * the ValidationResult is failed.
+ *
+ * @param attributes Attributes object containing the id to validate.
+ * @return Returns a [ValidationResult] that is success or failed with a
+ * failure message.
+ */
+ fun validateId(attributes: UAttributes): ValidationResult {
+ return when {
+ !attributes.hasId() -> ValidationResult.failure("Missing id")
+ !attributes.id.isUuid() -> {
+ ValidationResult.failure("Attributes must contain valid uProtocol UUID in id property")
+ }
+
+ else -> ValidationResult.success()
+ }
+ }
/**
* Validate the [UMessageType] attribute, it is required.
@@ -169,7 +174,7 @@ sealed class UAttributesValidator {
* @param attributes UAttributes object containing the message type to validate.
* @return Returns a [ValidationResult] that is success or failed with a failure message.
*/
- fun validateType(attributes: UAttributes): ValidationResult{
+ fun validateType(attributes: UAttributes): ValidationResult {
return if (type == attributes.type) {
ValidationResult.success()
} else {
@@ -206,12 +211,24 @@ sealed class UAttributesValidator {
object Publish : UAttributesValidator() {
override val className: String = "Publish"
override val type: UMessageType = UMessageType.UMESSAGE_TYPE_PUBLISH
+
+ /**
+ * Validate the sink UriPart for Publish events. Publish should not have a sink.
+ *
+ * @param attributes UAttributes object containing the sink to validate.
+ * @return Returns a [ValidationResult] that is success or failed with a
+ * failure message.
+ */
+ override fun validateSink(attributes: UAttributes): ValidationResult {
+ return if (attributes.hasSink()) ValidationResult.failure("Sink should not be present")
+ else ValidationResult.success()
+ }
}
/**
* Implements validations for UAttributes that define a message that is meant for notifications.
*/
-object Notification: UAttributesValidator(){
+object Notification : UAttributesValidator() {
override val className: String = "Notification"
override val type: UMessageType = UMessageType.UMESSAGE_TYPE_NOTIFICATION
@@ -223,12 +240,16 @@ object Notification: UAttributesValidator(){
* @return Returns a [ValidationResult] that is success or failed with a failure message.
*/
override fun validateSink(attributes: UAttributes): ValidationResult {
- if (!attributes.hasSink() || attributes.sink == UUri.getDefaultInstance()) {
- return ValidationResult.failure("Missing Sink")
+ return when {
+ !attributes.hasSink() || attributes.sink === UUri.getDefaultInstance() ->
+ ValidationResult.failure("Missing Sink")
+ !attributes.sink.isDefaultResourceId() -> ValidationResult.failure("Invalid Sink Uri")
+ else -> ValidationResult.success()
}
- return ValidationResult.success()
+
}
}
+
/**
* Implements validations for UAttributes that define a message that is meant for an RPC request.
*/
@@ -244,10 +265,10 @@ object Request : UAttributesValidator() {
* @return Returns a [ValidationResult] that is success or failed with a failure message.
*/
override fun validateSink(attributes: UAttributes): ValidationResult {
- return if (!attributes.hasSink()) {
- ValidationResult.failure("Missing Sink")
- } else {
- attributes.sink.validateRpcMethod()
+ return when {
+ !attributes.hasSink() -> ValidationResult.failure("Missing Sink")
+ !attributes.sink.isRpcMethod() -> ValidationResult.failure("Invalid Sink Uri")
+ else -> ValidationResult.success()
}
}
@@ -290,6 +311,7 @@ object Request : UAttributesValidator() {
object Response : UAttributesValidator() {
override val className: String = "Response"
override val type: UMessageType = UMessageType.UMESSAGE_TYPE_RESPONSE
+
/**
* 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.
@@ -298,10 +320,14 @@ object Response : UAttributesValidator() {
* @return Returns a [ValidationResult] that is success or failed with a failure message.
*/
override fun validateSink(attributes: UAttributes): ValidationResult {
- if (!attributes.hasSink() || attributes.sink === UUri.getDefaultInstance()) {
- return ValidationResult.failure("Missing Sink")
+ return when {
+ !attributes.hasSink() || attributes.sink === UUri.getDefaultInstance() ->
+ ValidationResult.failure("Missing Sink")
+
+ !attributes.sink.isRpcResponse() -> ValidationResult.failure("Invalid Sink Uri")
+ else -> ValidationResult.success()
}
- return attributes.sink.validateRpcResponse()
+
}
/**
@@ -315,7 +341,7 @@ object Response : UAttributesValidator() {
return ValidationResult.failure("Missing correlationId")
}
return if (!attributes.reqid.isUuid()) {
- ValidationResult.failure("Invalid correlationId [${attributes.reqid}]")
+ ValidationResult.failure("Invalid correlation UUID")
} else {
ValidationResult.success()
}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/README.adoc b/src/main/kotlin/org/eclipse/uprotocol/uri/README.adoc
index e30f446..49f1cb1 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/README.adoc
+++ b/src/main/kotlin/org/eclipse/uprotocol/uri/README.adoc
@@ -5,36 +5,12 @@
== Overview
-The following folder contains the everything but the data model for UUri (builders, serializers, validators, etc...) per https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc[uProtocol URI Specifications].
-The data model is defined in https://github.com/eclipse-uprotocol/uprotocol-core-api/blob/main/src/main/proto/uri.proto[uri.proto] and included as a dependency for this project.
-
-IMPORTANT: For more details about the data model, various formats (object, long, micro) and their uses, please refer to https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc[uProtocol URI Specifications].
+location of the uProtocol URI Factory serializers, validators, and builders per https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc[uProtocol URI Specifications].
== Using the SDK
-When building UUri, you can choose to populate it with only names, only numbers, or both (resolved). When you should use each is described the best practice section of https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc[uProtocol URI Specifications].
-
-=== Building an RPC Method
-[,kotlin]
-----
-val uri = uUri {
- authority = uAuthority {
- name = "MyDevice"
- ip = ByteString.copyFrom(InetAddress.getByName("192.168.1.100").address)
- }
- entity = uEntity {
- name = "Service"
- id = 10203
- versionMajor = 1
- }
- resource = UResourceFactory.createRpcRequest("Raise", 10)
- }
-----
-
-=== Validating
-[,kotlin]
+[source,java]
----
- val status:ValidationResult = uuri.validateRpcMethod()
- assertTrue(status.isSuccess())
+include::../../../../../../test/kotlin/org/eclipse/uprotocol/uri/UUriExamples.kt[]
----
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/UUriConstant.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/UUriConstant.kt
new file mode 100644
index 0000000..b79f62f
--- /dev/null
+++ b/src/main/kotlin/org/eclipse/uprotocol/uri/UUriConstant.kt
@@ -0,0 +1,36 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.uri
+
+object UUriConstant {
+ /**
+ * The minimum publish/notification topic id for a URI.
+ */
+ const val MIN_TOPIC_ID = 0x8000
+
+ /**
+ * The Default resource id.
+ */
+ const val DEFAULT_RESOURCE_ID = 0
+
+ /**
+ * major version wildcard
+ */
+ const val MAJOR_VERSION_WILDCARD = 0xFF
+
+ /**
+ * The wildcard id for a field.
+ */
+ const val WILDCARD_ID: Int = 0xFFFF
+}
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/Uri.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/Uri.kt
deleted file mode 100644
index 6d0385b..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/Uri.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.uri
-
-@JvmInline
-value class Uri(val value: String=""){
- override fun toString(): String {
- return value
- }
-}
-
-fun String.toUri(): Uri = Uri(this)
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/factory/UEntityFactory.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/factory/UEntityFactory.kt
deleted file mode 100644
index a51cebe..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/factory/UEntityFactory.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.uri.factory
-
-import com.google.protobuf.Descriptors.ServiceDescriptor
-import org.eclipse.uprotocol.UprotocolOptions
-import org.eclipse.uprotocol.v1.UEntity
-import org.eclipse.uprotocol.v1.uEntity
-
-
-/**
- * Create UEntity to/from proto information
- */
-object UEntityFactory {
- /**
- * Builds a UEntity for a protobuf generated code Service Descriptor.
- * @param descriptor The protobuf generated code Service Descriptor.
- * @return Returns a UEntity for a protobuf generated code Service Descriptor.
- */
- fun fromProto(descriptor: ServiceDescriptor): UEntity {
- return uEntity {
- descriptor.options.getExtension(UprotocolOptions.name)?.let{ name = it }
- descriptor.options.getExtension(UprotocolOptions.id)?.let{ id = it}
- descriptor.options.getExtension(UprotocolOptions.versionMajor)?.let{versionMajor = it}
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/factory/UUriFactory.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/factory/UUriFactory.kt
new file mode 100644
index 0000000..13d30e4
--- /dev/null
+++ b/src/main/kotlin/org/eclipse/uprotocol/uri/factory/UUriFactory.kt
@@ -0,0 +1,53 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.uri.factory
+
+import com.google.protobuf.Descriptors.ServiceDescriptor
+import org.eclipse.uprotocol.Uoptions
+import org.eclipse.uprotocol.v1.UUri
+import org.eclipse.uprotocol.v1.uUri
+
+object UUriFactory {
+ /**
+ * Builds a UUri for a protobuf generated code Service Descriptor.
+ *
+ * @param descriptor The protobuf generated code Service Descriptor.
+ * @param resourceId The resource id.
+ * @param authorityName The authority name.
+ * @return Returns a UUri for a protobuf generated code Service Descriptor.
+ */
+ fun fromProto(descriptor: ServiceDescriptor, resourceId: Int, authorityName: String? = null): UUri {
+ return uUri {
+ ueId = descriptor.options.getExtension(Uoptions.serviceId)
+ ueVersionMajor = descriptor.options.getExtension(Uoptions.serviceVersionMajor)
+ this.resourceId = resourceId
+ if (!authorityName.isNullOrEmpty()) {
+ this.authorityName = authorityName
+ }
+ }
+ }
+
+ /**
+ * Builds a UUri for a protobuf generated code Service Descriptor.
+ *
+ * @return Returns a UUri for a protobuf generated code Service Descriptor.
+ */
+ val ANY: UUri = uUri {
+ authorityName = "*"
+ ueId = 0xFFFF
+ ueVersionMajor = 0xFF
+ resourceId = 0xFFFF
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/IpAddress.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/IpAddress.kt
deleted file mode 100644
index 6cee2e6..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/IpAddress.kt
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.eclipse.uprotocol.uri.serializer
-
-
-object IpAddress {
- fun toBytes(ipAddress: String): ByteArray {
- return if (ipAddress.isEmpty()) {
- ByteArray(0)
- } else if (isValidIPv4Address(ipAddress)) {
- convertIPv4ToByteArray(ipAddress)
- } else if (isValidIPv6Address(ipAddress)) {
- convertIPv6ToByteArray(ipAddress)
- } else {
- ByteArray(0)
- }
- }
-
- fun isValid(ipAddress: String): Boolean {
- return ipAddress.isNotEmpty() && (isValidIPv4Address(ipAddress) || isValidIPv6Address(ipAddress))
- }
-
- private fun isValidIPv4Address(ipAddress: String): Boolean {
- val octetRange = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
- val ipv4Regex = """^$octetRange\.$octetRange\.$octetRange\.$octetRange$""".toRegex()
- return ipAddress.matches(ipv4Regex)
- }
-
- private fun convertIPv4ToByteArray(ipAddress: String): ByteArray {
- val octets = ipAddress.split(".")
- return ByteArray(4) { i -> octets[i].toInt().toByte() }
- }
-
- private fun isValidIPv6Address(ipAddress: String): Boolean {
- // Split the address into groups using the colon separator
- val groups = ipAddress.split(":".toRegex()).dropLastWhile { it.isEmpty() }
- // Check the number of groups
- if (groups.size > 8) {
- return false // Too many groups
- }
-
- var hasDoubleColon = false
- var emptyGroups = 0
-
- for (group in groups) {
- // Check for an empty group
- if (group.isEmpty()) {
- emptyGroups++
- // Double colon can only appear once
- if (emptyGroups > 1) {
- return false
- }
- hasDoubleColon = true
- } else {
- // Check each character in the group
- for (element in group) {
- // Check if the character is a valid hexadecimal digit
- if (!isValidHexDigit(element)) {
- return false
- }
- }
- }
- }
-
- // Check if the address ends with a double colon
- if (ipAddress.endsWith(":")) {
- // We already had an empty group so crap out
- if (emptyGroups > 0) {
- return false
- }
- hasDoubleColon = true
- }
-
- // Check the final number of groups
- if (!hasDoubleColon && groups.size != 8) {
- return false // Not enough groups
- }
-
- return true
- }
-
- private fun isValidHexDigit(c: Char): Boolean {
- return (c in 'a'..'f') || (c in '0'..'9') || (c in 'A'..'F')
- }
-
- private fun convertIPv6ToByteArray(ipAddress: String): ByteArray {
- // Split the address into groups using the colon separator
- val groups = ipAddress.split(":".toRegex()).dropLastWhile { it.isEmpty() }
- // Initialize the byte array
- val ipAddressBytes = ByteArray(16)
-
- // Index to keep track of the current position in the byte array
- var index = 0
-
- for (group in groups) {
- // Check for an empty group
- if (group.isEmpty()) {
- // Calculate the number of empty groups needed
- val emptyGroups = 8 - (groups.size - 1)
-
- // Fill the empty groups with zeros
- repeat(emptyGroups * 2) {
- ipAddressBytes[index++] = 0
- }
- } else {
- // Convert the group to a 16-bit integer
- val value = group.toInt(16)
-
- // Split the value into two bytes
- ipAddressBytes[index++] = ((value shr 8) and 0xFF).toByte()
- ipAddressBytes[index++] = (value and 0xFF).toByte()
- }
- }
-
- return ipAddressBytes
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.kt
deleted file mode 100644
index 1fb5d84..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/LongUriSerializer.kt
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.uri.serializer
-
-import org.eclipse.uprotocol.uri.validator.isEmpty
-import org.eclipse.uprotocol.v1.*
-
-/**
- * UUri Serializer that serializes a UUri to a long format string per
- * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc
- */
-class LongUriSerializer private constructor() : UriSerializer {
- /**
- * Support for serializing [UUri] objects into their String format.
- * @param uri [UUri] object to be serialized to the String format.
- * @return Returns the String format of the supplied [UUri] that can be used as a sink or a source in a uProtocol publish communication.
- */
- override fun serialize(uri: UUri): String {
- if (uri.isEmpty()) {
- return ""
- }
- val sb = StringBuilder()
- if (uri.hasAuthority()) {
- sb.append("//")
- sb.append(uri.authority.name)
- }
- sb.append("/")
- sb.append(buildSoftwareEntityPartOfUri(uri.entity))
- sb.append(buildResourcePartOfUri(uri))
- return sb.toString().replace("/+$".toRegex(), "")
- }
-
- /**
- * Deserialize a String into a UUri object.
- * @param uri A long format uProtocol URI.
- * @return Returns an UUri data object.
- */
-
- override fun deserialize(uri: String): UUri {
- if (uri.isBlank()) {
- return UUri.getDefaultInstance()
- }
- val uuri: String = if (uri.contains(":")) uri.substring(uri.indexOf(":") + 1) else uri
- .replace('\\', '/')
- val isLocal: Boolean = !uuri.startsWith("//")
- val uriParts: List = removeEmpty(uuri.split("/".toRegex()))
- val numberOfPartsInUri = uriParts.size
- if (numberOfPartsInUri == 0 || numberOfPartsInUri == 1) {
- return UUri.getDefaultInstance()
- }
- val useName: String
- var useVersion = ""
- var uResource: UResource? = null
- var uAuthority: UAuthority? = null
- if (isLocal) {
- useName = uriParts[1]
- if (numberOfPartsInUri > 2) {
- useVersion = uriParts[2]
- if (numberOfPartsInUri > 3) {
- uResource = parseFromString(
- uriParts[3]
- )
- }
- }
- } else {
- // If authority is blank, it is an error
- if (uriParts[2].isBlank()) {
- return UUri.getDefaultInstance()
- }
- uAuthority = uAuthority { name = uriParts[2] }
- if (uriParts.size > 3) {
- useName = uriParts[3]
- if (numberOfPartsInUri > 4) {
- useVersion = uriParts[4]
- if (numberOfPartsInUri > 5) {
- uResource = parseFromString(
- uriParts[5]
- )
- }
- }
- } else {
- return uUri { authority = uAuthority }
- }
- }
- var useVersionInt: Int? = null
- try {
- if (useVersion.isNotBlank()) {
- useVersionInt = Integer.valueOf(useVersion)
- }
- } catch (ignored: NumberFormatException) {
- return UUri.getDefaultInstance()
- }
-
- return uUri {
- uAuthority?.let { authority = it }
- uResource?.let { resource = it }
- entity = uEntity {
- name = useName
- useVersionInt?.let { versionMajor = it }
- }
-
- }
- }
-
- companion object {
- val INSTANCE = LongUriSerializer()
-
- private fun buildResourcePartOfUri(uri: UUri): String {
- if (!uri.hasResource()) {
- return ""
- }
- val uResource: UResource = uri.resource
- val sb = StringBuilder("/")
- sb.append(uResource.name)
- if (uResource.hasInstance()) {
- sb.append(".").append(uResource.instance)
- }
- if (uResource.hasMessage()) {
- sb.append("#").append(uResource.message)
- }
- return sb.toString()
- }
-
- /**
- * Create the service part of the uProtocol URI from a software entity object.
- * @param use Software Entity representing a service or an application.
- */
- private fun buildSoftwareEntityPartOfUri(use: UEntity): String {
- val sb = StringBuilder(use.name.trim())
- sb.append("/")
- if (use.versionMajor > 0) {
- sb.append(use.versionMajor)
- }
- return sb.toString()
- }
-
- /**
- * 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.
- */
- private fun parseFromString(resourceString: String): UResource {
- val parts: List = removeEmpty(resourceString.split("#"))
- val nameAndInstance = parts[0]
- val nameAndInstanceParts: List = removeEmpty(nameAndInstance.split("."))
- val resourceName = nameAndInstanceParts[0]
- val resourceInstance = if (nameAndInstanceParts.size > 1) nameAndInstanceParts[1] else null
- val resourceMessage = if (parts.size > 1) parts[1] else null
-
- return uResource {
- name = resourceName
- resourceInstance?.let { instance = it }
- resourceMessage?.let { message = it }
- if (resourceName.contains("rpc") && resourceInstance != null && resourceInstance.contains("response")) {
- id = 0
- }
- }
- }
-
- fun removeEmpty(parts: List): List {
- val result = parts.toMutableList()
-
- // Iterate through the list in reverse and remove empty strings
- while (result.isNotEmpty() && result.last().isEmpty()) {
- result.removeAt(result.size - 1)
- }
- return result
-
- }
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.kt
deleted file mode 100644
index f445b25..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/MicroUriSerializer.kt
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.uri.serializer
-
-import com.google.protobuf.ByteString
-import org.eclipse.uprotocol.uri.validator.isEmpty
-import org.eclipse.uprotocol.uri.validator.isMicroForm
-import org.eclipse.uprotocol.v1.*
-import java.io.ByteArrayOutputStream
-import java.io.IOException
-
-/**
- * UUri Serializer that serializes a UUri to a byte[] (micro format) per
- * [...](https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc)
- */
-class MicroUriSerializer private constructor() : UriSerializer {
- /**
- * The type of address used for Micro URI.
- */
- private enum class AddressType(private val value: Int) {
- LOCAL(0), IPv4(1), IPv6(2), ID(3);
-
- fun getValue(): Byte {
- return value.toByte()
- }
-
- companion object {
- fun from(value: Int): AddressType? {
- return entries.toTypedArray().firstOrNull {
- it.value == value
- }
- }
- }
- }
-
- /**
- * Serialize a UUri into a byte[] following the Micro-URI specifications.
- * @param uri The [UUri] data object.
- * @return Returns a byte[] representing the serialized [UUri].
- */
- override fun serialize(uri: UUri): ByteArray {
- if (uri.isEmpty() || !uri.isMicroForm()) {
- return ByteArray(0)
- }
- val uEId = uri.entity.id
- val uResourceId = uri.resource.id
- val os = ByteArrayOutputStream()
- // UP_VERSION
- os.write(UP_VERSION.toInt())
- val type = if (uri.authority.hasIp()) {
- val length = uri.authority.getIp().size()
- when (length) {
- 4 -> {
- AddressType.IPv4
- }
-
- 16 -> {
- AddressType.IPv6
- }
-
- else -> {
- return ByteArray(0)
- }
- }
- } else if (uri.authority.hasId()) {
- AddressType.ID
- } else {
- AddressType.LOCAL
- }
-
- os.write(type.getValue().toInt())
-
- // URESOURCE_ID
- os.write(uResourceId shr 8)
- os.write(uResourceId)
-
- // UENTITY_ID
- os.write(uEId shr 8)
- os.write(uEId)
-
- // UE_VERSION
- os.write((if (uri.entity.versionMajor == 0) 0.toByte() else uri.entity.versionMajor).toInt())
-
- // UNUSED
- os.write(0.toByte().toInt())
-
- // Populating the UAuthority
- if (type != AddressType.LOCAL) {
-
- // Write the ID length if the type is ID
- if (type == AddressType.ID) {
- os.write(uri.authority.id.size())
- }
- try {
- if (uri.authority.hasIp()) {
- os.write(uri.authority.getIp().toByteArray())
- } else {
- os.write(uri.authority.getId().toByteArray())
- }
- } catch (e: IOException) {
- return ByteArray(0)
- }
- }
- return os.toByteArray()
- }
-
- /**
- * Deserialize a byte[] into a [UUri] object.
- * @param uri A byte[] uProtocol micro URI.
- * @return Returns an [UUri] data object from the serialized format of a microUri.
- */
- override fun deserialize(uri: ByteArray): UUri {
- if (uri.size < LOCAL_MICRO_URI_LENGTH) {
- return UUri.getDefaultInstance()
- }
-
- // Need to be version 1
- if (uri[0].toInt() != 0x1) {
- return UUri.getDefaultInstance()
- }
- val uResourceId = uri[2].toInt() and 0xFF shl 8 or (uri[3].toInt() and 0xFF)
- val type: AddressType = AddressType.from(uri[1].toInt()) ?: return UUri.getDefaultInstance()
-
- // Validate Type is found
-
- // Validate that the microUri is the correct length for the type
- val addressType: AddressType = type
- if (addressType == AddressType.LOCAL && uri.size != LOCAL_MICRO_URI_LENGTH) {
- return UUri.getDefaultInstance()
- } else if (addressType == AddressType.IPv4 && uri.size != IPV4_MICRO_URI_LENGTH) {
- return UUri.getDefaultInstance()
- } else if (addressType == AddressType.IPv6 && uri.size != IPV6_MICRO_URI_LENGTH) {
- return UUri.getDefaultInstance()
- }
-
- // UENTITY_ID
- val ueId = uri[4].toInt() and 0xFF shl 8 or (uri[5].toInt() and 0xFF)
-
- // UE_VERSION
- val uiVersion: Int = uri[6].toUByte().toInt()
-
- // Calculate uAuthority
- var uAuthority: UAuthority? = null
- when (addressType) {
-
- AddressType.IPv4, AddressType.IPv6 -> uAuthority = uAuthority {
- ip = ByteString.copyFrom(
- uri, 8, if (addressType == AddressType.IPv4) 4 else 16
- )
- }
-
- AddressType.ID -> {
- val length: Int = uri[8].toUByte().toInt()
-
- uAuthority = uAuthority {
- id = ByteString.copyFrom(
- uri, 9, length
- )
- }
- }
-
- else -> {}
- }
-
- return uUri {
- entity = uEntity {
- id = ueId
- versionMajor = uiVersion
- }
- resource = uResource {
- from(uResourceId)
- }
- uAuthority?.let { authority = it }
- }
- }
-
- companion object {
- const val LOCAL_MICRO_URI_LENGTH = 8 // local micro URI length
- const val IPV4_MICRO_URI_LENGTH = 12 // IPv4 micro URI length
- const val IPV6_MICRO_URI_LENGTH = 24 // IPv6 micro UriPart length
- const val UP_VERSION: Byte = 0x1 // UP version
- val INSTANCE = MicroUriSerializer()
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.kt
deleted file mode 100644
index 060ec1d..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/ShortUriSerializer.kt
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.uri.serializer
-
-import com.google.protobuf.ByteString
-import org.eclipse.uprotocol.uri.serializer.IpAddress.isValid
-import org.eclipse.uprotocol.uri.serializer.IpAddress.toBytes
-import org.eclipse.uprotocol.uri.validator.isEmpty
-import org.eclipse.uprotocol.v1.*
-import java.net.InetAddress
-import java.net.UnknownHostException
-
-
-/**
- * UUri Serializer that serializes a UUri to a Short format string per
- * https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc
- */
-class ShortUriSerializer private constructor() : UriSerializer {
- /**
- * 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 fun serialize(uri: UUri): String {
- if (uri.isEmpty()) {
- return ""
- }
-
- val sb = StringBuilder()
-
- if (uri.hasAuthority()) {
- val authority: UAuthority = uri.authority
- if (authority.hasIp()) {
- try {
- sb.append("/")
- sb.append(InetAddress.getByAddress(authority.ip.toByteArray()))
- } catch (e: UnknownHostException) {
- return ""
- }
- } else if (authority.hasId()) {
- sb.append("//")
- sb.append(authority.id.toStringUtf8())
- } else {
- return ""
- }
- }
- sb.append("/")
-
- sb.append(uri.entity.buildUriString())
-
- sb.append(uri.buildUriString())
-
- return sb.toString().replace("/+$", "")
- }
-
- /**
- * Deserialize a String into a UUri object.
- * @param uri A short format uProtocol URI.
- * @return Returns an UUri data object.
- */
- override fun deserialize(uri: String): UUri {
- if (uri.isBlank()) {
- return UUri.getDefaultInstance()
- }
-
- val uriString: String =
- if (uri.contains(":")) uri.substring(uri.indexOf(":") + 1) else uri.replace('\\', '/')
-
- val isLocal = !uriString.startsWith("//")
-
- val uriParts = uriString.split("/".toRegex()).dropLastWhile { it.isEmpty() }
- val numberOfPartsInUri = uriParts.size
-
- if (numberOfPartsInUri < 2) {
- return UUri.getDefaultInstance()
- }
-
- val uEId: String
- var ueVersion = ""
-
- var uResource: UResource? = null
-
- var uAuthority: UAuthority? = null
-
- if (isLocal) {
- uEId = uriParts[1]
- if (numberOfPartsInUri > 2) {
- ueVersion = uriParts[2]
-
- if (numberOfPartsInUri > 3) {
- uResource = parseFromString(uriParts[3])
- }
- // Too many parts now
- if (numberOfPartsInUri > 4) {
- return UUri.getDefaultInstance()
- }
- }
- } else {
- // If authority is blank, it is an error
- if (uriParts[2].isBlank()) {
- return UUri.getDefaultInstance()
- }
-
- // Try if it is an IP address, if not then it must be an ID
- uAuthority = uAuthority {
- if (isValid(uriParts[2])) {
- ip = ByteString.copyFrom(toBytes(uriParts[2]))
- } else {
- id = ByteString.copyFromUtf8(uriParts[2])
- }
- }
-
- if (uriParts.size > 3) {
- uEId = uriParts[3]
- if (numberOfPartsInUri > 4) {
- ueVersion = uriParts[4]
-
- if (numberOfPartsInUri > 5) {
- uResource = parseFromString(uriParts[5])
- }
- // Way too many parts in the URI
- if (numberOfPartsInUri > 6) {
- return UUri.getDefaultInstance()
- }
- }
- } else {
- return uUri {
- authority = uAuthority
- }
- }
- }
-
- var useVersionInt: Int? = null
- var ueIdInt: Int? = null
- try {
- if (ueVersion.isNotBlank()) {
- useVersionInt = ueVersion.toInt()
- }
-
- if (uEId.isNotBlank()) {
- ueIdInt = uEId.toInt()
- }
- } catch (ignored: java.lang.NumberFormatException) {
- return UUri.getDefaultInstance()
- }
-
- return uUri {
- entity = uEntity {
-
- ueIdInt?.let { id = it }
- useVersionInt?.let { versionMajor = it }
-
- }
- uAuthority?.let { authority = it }
- uResource?.let { resource = it }
- }
-
- }
-
- companion object {
- val INSTANCE = ShortUriSerializer()
-
- /**
- * Static factory method for creating a UResource using a string value
- * @param resourceString String that contains the UResource id.
- * @return Returns a UResource object.
- */
- private fun parseFromString(resourceString: String): UResource {
- return try {
- uResource { from(resourceString.toInt()) }
- } catch (ignored: NumberFormatException) {
- UResource.getDefaultInstance()
- }
- }
-
- private fun UUri.buildUriString(): String {
- return if (hasResource()) {
- "/${resource.id}"
- } else {
- ""
- }
- }
-
- /**
- * Create the service part of the uProtocol URI from an software entity object.
- */
- private fun UEntity.buildUriString(): String {
- val versionStr = if (versionMajor > 0) {
- versionMajor
- } else {
- ""
- }
- return "$id/$versionStr"
- }
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializer.kt
index 006d8a0..67fd21d 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializer.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializer.kt
@@ -1,49 +1,112 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uri.serializer
+
+import org.eclipse.uprotocol.uri.UUriConstant.MAJOR_VERSION_WILDCARD
+import org.eclipse.uprotocol.uri.UUriConstant.WILDCARD_ID
+import org.eclipse.uprotocol.uri.validator.isEmpty
import org.eclipse.uprotocol.v1.UUri
+
+/**
+ * Support for serializing [UUri] objects into their String format.
+ * @return Returns the String format of the supplied [UUri] that can be used as a sink or a source in a uProtocol publish communication.
+ */
+fun UUri.serialize(): String {
+ if (isEmpty()) {
+ return ""
+ }
+
+ val sb = StringBuilder()
+
+ if (authorityName.isNotBlank()) {
+ sb.append("//")
+ sb.append(authorityName)
+ }
+
+ sb.append("/")
+ sb.append(Integer.toHexString(ueId))
+ sb.append("/")
+ sb.append(Integer.toHexString(ueVersionMajor))
+ sb.append("/")
+ sb.append(Integer.toHexString(resourceId))
+ return sb.toString().replace("/+$", "")
+}
/**
- * UUris are used in transport layers and hence need to be serialized.
- * Each transport supports different serialization formats.
- * For more information, please refer to [...](https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/basics/uri.adoc)
- * @param The data structure that the UUri will be serialized into. For example String or byte[].
- */
-interface UriSerializer {
- /**
- * Deserialize from the format to a [UUri].
- * @param uri serialized UUri.
- * @return Returns a [UUri] object from the serialized format from the wire.
- */
- fun deserialize(uri: T): UUri
-
- /**
- * Serialize from a [UUri] to a specific serialization format.
- * @param uri UUri object to be serialized to the format T.
- * @return Returns the [UUri] in the transport serialized format.
- */
- fun serialize(uri: UUri): T
-}
\ No newline at end of file
+ * Deserialize from the String to a [UUri].
+ * @return Returns a [UUri] object from the serialized format from the wire.
+ */
+fun String.deserializeAsUUri(): UUri {
+ if (isBlank()) {
+ return UUri.getDefaultInstance()
+ }
+ val uuri: String = if (contains(":")) substring(indexOf(":") + 1) else
+ replace('\\', '/')
+ val isLocal: Boolean = !uuri.startsWith("//")
+ val uriParts: List = uuri.split("/").dropLastWhile { it.isEmpty() }
+ val numberOfPartsInUri = uriParts.size
+ if (numberOfPartsInUri == 0 || numberOfPartsInUri == 1) {
+ return UUri.getDefaultInstance()
+ }
+
+ // TODO: optimize the logic
+ val builder = UUri.newBuilder()
+ try {
+ if (isLocal) {
+ builder.setUeId(Integer.parseUnsignedInt(uriParts[1], 16))
+ if (numberOfPartsInUri > 2) {
+ builder.setUeVersionMajor(Integer.parseUnsignedInt(uriParts[2], 16))
+
+ if (numberOfPartsInUri > 3) {
+ builder.setResourceId(Integer.parseUnsignedInt(uriParts[3], 16))
+ }
+ }
+ } else {
+ // If authority is blank, it is an error
+ if (uriParts[2].isBlank()) {
+ return UUri.getDefaultInstance()
+ }
+ builder.setAuthorityName(uriParts[2])
+
+ if (uriParts.size > 3) {
+ builder.setUeId(Integer.parseUnsignedInt(uriParts[3], 16))
+ if (numberOfPartsInUri > 4) {
+ builder.setUeVersionMajor(Integer.parseUnsignedInt(uriParts[4], 16))
+
+ if (numberOfPartsInUri > 5) {
+ builder.setResourceId(Integer.parseUnsignedInt(uriParts[5], 16))
+ }
+ }
+ }
+ }
+ } catch (e: NumberFormatException) {
+ return UUri.getDefaultInstance()
+ }
+
+
+ // Ensure the major version is less than the wildcard
+ if (builder.ueVersionMajor > MAJOR_VERSION_WILDCARD) {
+ return UUri.getDefaultInstance()
+ }
+
+
+ // Ensure the resource id is less than the wildcard
+ if (builder.resourceId > WILDCARD_ID) {
+ return UUri.getDefaultInstance()
+ }
+
+ return builder.build()
+}
+
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uri/validator/UriValidator.kt b/src/main/kotlin/org/eclipse/uprotocol/uri/validator/UriValidator.kt
index 2a67761..57d4361 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uri/validator/UriValidator.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/uri/validator/UriValidator.kt
@@ -1,80 +1,20 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uri.validator
+import org.eclipse.uprotocol.uri.UUriConstant.DEFAULT_RESOURCE_ID
+import org.eclipse.uprotocol.uri.UUriConstant.MIN_TOPIC_ID
import org.eclipse.uprotocol.v1.*
-import org.eclipse.uprotocol.validation.ValidationResult
-import kotlin.contracts.ExperimentalContracts
-import kotlin.contracts.contract
-
-
-/**
- * Validate a [UUri] to ensure that it has at least a name for the uEntity.
- *
- * @return Returns UStatus containing a success or a failure with the error message.
- */
-fun UUri.validate(): ValidationResult {
- if (isEmpty()) {
- return ValidationResult.failure("Uri is empty.")
- }
- if (hasAuthority() && !authority.isRemote()) {
- return ValidationResult.failure("Uri is remote missing uAuthority.")
- }
- return if (entity.name.isBlank()) {
- ValidationResult.failure("Uri is missing uSoftware Entity name.")
- } else ValidationResult.success()
-}
-
-/**
- * Validate a [UUri] that is meant to be used as an RPC method URI. Used in Request sink values and Response source values.
- *
- * @return Returns UStatus containing a success or a failure with the error message.
- */
-fun UUri.validateRpcMethod(): ValidationResult {
- val status: ValidationResult = validate()
- if (status.isFailure()) {
- return status
- }
- return if (!isRpcMethod()) {
- ValidationResult.failure("Invalid RPC method uri. Uri should be the method to be called, or method from response.")
- } else ValidationResult.success()
-}
-
-/**
- * Validate a [UUri] that is meant to be used as an RPC response URI. Used in Request source values and Response sink values.
- *
- * @return Returns UStatus containing a success or a failure with the error message.
- */
-fun UUri.validateRpcResponse(): ValidationResult {
- val status: ValidationResult = validate()
- if (status.isFailure()) {
- return status
- }
- return if (!isRpcResponse()) {
- ValidationResult.failure("Invalid RPC response type.")
- } else ValidationResult.success()
-}
/**
* Returns true if URI is of type RPC. A UUri is of type RPC if it contains the word rpc in the resource name
@@ -83,29 +23,9 @@ fun UUri.validateRpcResponse(): ValidationResult {
* @return Returns true if URI is of type RPC.
*/
fun UUri.isRpcMethod(): Boolean {
-
- return resource.isRpcMethod()
-}
-
-/**
- * Returns true if URI is of type RPC. A UUri is of type RPC if it contains the word rpc in the resource name
- * and has an instance name and/or the id is less than MIN_TOPIC_ID.
- *
- * @return Returns true if URI is of type RPC.
- */
-fun UResource.isRpcMethod(): Boolean {
- return name == "rpc" && (hasInstance() && instance.trim().isNotEmpty() || (hasId() && id < MIN_TOPIC_ID))
-}
-
-/**
- * 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.
- */
-fun UUri.isResolved(): Boolean {
- return isLongForm() && isMicroForm()
+ return !isEmpty() &&
+ resourceId != DEFAULT_RESOURCE_ID &&
+ resourceId < MIN_TOPIC_ID
}
/**
@@ -114,7 +34,7 @@ fun UUri.isResolved(): Boolean {
* @return Returns true if URI is of type RPC response.
*/
fun UUri.isRpcResponse(): Boolean {
- return resource == uResource { forRpcResponse() }
+ return isDefaultResourceId()
}
/**
@@ -136,81 +56,21 @@ fun UUri.isNotEmpty(): Boolean {
}
/**
- * Returns true if URI contains numbers so that it can be serialized into micro format.
- *
- * @return Returns true if URI contains numbers so that it can be serialized into micro format.
- */
-fun UUri.isMicroForm(): Boolean {
- return !isEmpty() && entity.hasId() && resource
- .hasId() && authority.isMicroForm()
-}
-
-/**
- * check if UAuthority can be represented in micro format. Micro UAuthorities are local or ones
- * that contain IP address or IDs.
+ * Returns true if URI has the resource id of 0.
*
- * @return Returns true if UAuthority can be represented in micro format
+ * @return Returns true if URI has a resource id of 0.
*/
-fun UAuthority?.isMicroForm(): Boolean {
- return isLocal() || (this?.hasIp() == true || this?.hasId() == true)
+fun UUri.isDefaultResourceId(): Boolean {
+ return !isEmpty() && resourceId == DEFAULT_RESOURCE_ID
}
/**
- * Returns true if URI contains names so that it can be serialized into long format.
+ * Returns true if URI is of type Topic used for publish and notifications.
*
- * @return Returns true if URI contains names so that it can be serialized into long format.
+ * @return Returns true if URI is of type Topic.
*/
-fun UUri.isLongForm(): Boolean {
- return !isEmpty() &&
- authority.isLongForm() &&
- entity.getName().isNotBlank() && resource.getName().isNotBlank()
+fun UUri.isTopic(): Boolean {
+ return !isEmpty() && resourceId >= MIN_TOPIC_ID
}
-/**
- * Returns true if UAuthority is local or contains names so that it can be serialized into long format.
- *
- * @return Returns true if URI contains names so that it can be serialized into long format.
- */
-@OptIn(ExperimentalContracts::class)
-fun UAuthority?.isLongForm(): Boolean {
- contract {
- returns(true) implies (this@isLongForm is UAuthority)
- }
- return (this != null) && ( this.isLocal() || (this.hasName() && this.name.isNotBlank()))
-}
-/**
- * Returns true if UAuthority is local meaning there is no name/ip/id set.
- *
- * @return Returns true if UAuthority is local meaning the Authority is not populated with name, ip and id
- */
-@OptIn(ExperimentalContracts::class)
-fun UAuthority?.isLocal(): Boolean {
- contract {
- returns(true) implies (this@isLocal is UAuthority)
- }
- return (this != null) && this == UAuthority.getDefaultInstance()
-}
-
-/**
- * Returns true if UAuthority is remote meaning the name and/or ip/id is populated.
- *
- * @return Returns true if UAuthority is remote meaning the name and/or ip/id is populated.
- */
-@OptIn(ExperimentalContracts::class)
-fun UAuthority?.isRemote(): Boolean {
- contract {
- returns(true) implies (this@isRemote is UAuthority)
- }
- return (this != null) && this != UAuthority.getDefaultInstance()
-
-}
-
-/**
- * Return True of the UUri is Short form. A UUri that is micro form (contains numbers) can
- * also be a Short form Uri.
- * @return Returns true if contains ids can can be serialized to short format.
- */
-fun UUri.isShortForm(): Boolean {
- return isMicroForm()
-}
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/README.adoc b/src/main/kotlin/org/eclipse/uprotocol/uuid/README.adoc
index 7d03aec..9ec32ea 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/README.adoc
+++ b/src/main/kotlin/org/eclipse/uprotocol/uuid/README.adoc
@@ -13,8 +13,7 @@ Implementation of https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/
val uuid: UUID = UUIDV8()
val version: UUIDVersion = uuid.getVersion()
val time: Long? = uuid.getTime()
- val bytes = MicroUuidSerializer.INSTANCE.serialize(uuid)
- val uuidString = LongUuidSerializer.INSTANCE.serialize(uuid)
+ val uuidString = uuid.serialize()
assertNotNull(uuid)
assertFalse(uuid.isUuidv6())
@@ -22,14 +21,9 @@ Implementation of https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/
assertTrue(version.isPresent)
assertEquals(version, UuidUtils.Version.VERSION_UNKNOWN)
assertFalse(time.isPresent)
- assertTrue(bytes.isNotEmpty())
assertFalse(uuidString.isBlank())
- val uuid1: UUID = MicroUuidSerializer.INSTANCE.deserialize(bytes)
+ val uuid1: UUID = uuidString.deserializeAsUUID()
assertTrue(uuid1 == UUID.getDefaultInstance())
assertEquals(uuid, uuid1)
-
- val uuid2: UUID = LongUuidSerializer.INSTANCE.deserialize(uuidString)
- assertTrue(uuid2 == UUID.getDefaultInstance())
- assertEquals(uuid, uuid2)
----
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidFactory.kt b/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidFactory.kt
index 7ceb0fc..1720556 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidFactory.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidFactory.kt
@@ -1,24 +1,13 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtils.kt b/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtils.kt
index e8fc4ea..5b6f481 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtils.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtils.kt
@@ -1,24 +1,13 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
@@ -27,7 +16,6 @@ package org.eclipse.uprotocol.uuid.factory
import com.github.f4b6a3.uuid.enums.UuidVariant
import com.github.f4b6a3.uuid.util.UuidTime
import com.github.f4b6a3.uuid.util.UuidUtil
-import org.eclipse.uprotocol.v1.UAttributes
import org.eclipse.uprotocol.v1.UUID
@@ -128,16 +116,6 @@ fun UUID.getRemainingTime(ttl: Int): Long? {
}
}
-/**
- * Calculates the remaining time until the expiration of the event identified by the given UAttributes.
- *
- * @return The remaining time in milliseconds until the event expires,
- * or null if the attributes do not contain TTL information or the creation time cannot be determined.
- */
-fun UAttributes.getRemainingTime():Long? {
- return if (hasTtl()) id.getRemainingTime(ttl) else null
-}
-
/**
* Checks if the event identified by the given UUID has expired based on the specified time-to-live (TTL).
*
@@ -149,16 +127,6 @@ fun UUID.isExpired(ttl: Int): Boolean {
return ttl > 0 && getRemainingTime(ttl) == null
}
-/**
- * Checks if the event identified by the given UAttributes has expired.
- *
- * @return true if the event has expired, false otherwise.Returns false if the attributes do not contain TTL
- * information or creation time cannot be determined.
- */
-fun UAttributes.isExpired(): Boolean {
- return hasTtl() && id.isExpired(ttl)
-}
-
/**
* UUID Version
*/
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/LongUuidSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/LongUuidSerializer.kt
deleted file mode 100644
index df14bb8..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/LongUuidSerializer.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.eclipse.uprotocol.uuid.serializer
-
-import org.eclipse.uprotocol.v1.UUID
-import org.eclipse.uprotocol.v1.uUID
-
-/**
- * UUID Serializer interface used to serialize/deserialize UUIDs to/from a string
- */
-class LongUuidSerializer private constructor() : UuidSerializer {
- override fun deserialize(uuid: String?): UUID {
- return if (uuid.isNullOrBlank()) {
- UUID.getDefaultInstance()
- } else try {
- val uuidJava = java.util.UUID.fromString(uuid)
- uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
- }
-
- } catch (e: IllegalArgumentException) {
- UUID.getDefaultInstance()
- }
- }
-
- override fun serialize(uuid: UUID?): String {
- return if (uuid == null) "" else java.util.UUID(uuid.msb, uuid.lsb).toString()
- }
-
- companion object {
- val INSTANCE : LongUuidSerializer by lazy { LongUuidSerializer() }
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/MicroUuidSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/MicroUuidSerializer.kt
deleted file mode 100644
index fdd3a85..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/MicroUuidSerializer.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.eclipse.uprotocol.uuid.serializer
-
-import org.eclipse.uprotocol.v1.UUID
-import org.eclipse.uprotocol.v1.uUID
-import java.nio.ByteBuffer
-import java.nio.ByteOrder
-
-class MicroUuidSerializer private constructor() : UuidSerializer {
- override fun deserialize(uuid: ByteArray?): UUID {
- if (uuid == null || uuid.size != 16) {
- return UUID.getDefaultInstance()
- }
- val byteBuffer = ByteBuffer.wrap(uuid)
- return uUID {
- msb = byteBuffer.getLong()
- lsb = byteBuffer.getLong()
- }
- }
-
- override fun serialize(uuid: UUID?): ByteArray {
- if (uuid == null) {
- return ByteArray(0)
- }
- val b = ByteArray(16)
- return ByteBuffer.wrap(b).order(ByteOrder.BIG_ENDIAN).putLong(uuid.msb).putLong(uuid.lsb).array()
- }
-
- companion object {
- val INSTANCE = MicroUuidSerializer()
- }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializer.kt b/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializer.kt
index 07517ec..acb295c 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializer.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializer.kt
@@ -1,46 +1,43 @@
-/*
- * Copyright (c) 2023 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uuid.serializer
import org.eclipse.uprotocol.v1.UUID
+import org.eclipse.uprotocol.v1.uUID
+
/**
- * UUID Serializer interface used to serialize/deserialize UUIDs to/from either Long (string) or micro (bytes) form
- * @param The data structure that the UUID will be serialized into. For example String or byte[].
- */
-interface UuidSerializer {
- /**
- * Deserialize from the format to a [UUID].
- * @param uuid serialized UUID.
- * @return Returns a [UUID] object from the serialized format from the wire.
- */
- fun deserialize(uuid: T): UUID
+ * Deserialize from a specific serialization format to a [UUID].
+ * @return Returns the [UUID] object
+ */
+fun String.deserializeAsUUID(): UUID {
+ return try {
+ require(this.isNotBlank())
+ val uuidJava = java.util.UUID.fromString(this)
+ uUID {
+ msb = uuidJava.mostSignificantBits
+ lsb = uuidJava.leastSignificantBits
+ }
+ } catch (e: IllegalArgumentException) {
+ UUID.getDefaultInstance()
+ }
+}
- /**
- * Serialize from a [UUID] to a specific serialization format.
- * @param uuid UUID object to be serialized to the format T.
- * @return Returns the [UUID] in the transport serialized format.
- */
- fun serialize(uuid: UUID?): T
+/**
+ * Serialize from a [UUID] to a specific serialization format.
+ * @return Returns the [UUID] in the transport serialized format.
+ */
+fun UUID.serialize(): String {
+ return java.util.UUID(msb, lsb).toString()
}
+
diff --git a/src/main/kotlin/org/eclipse/uprotocol/uuid/validate/UuidValidator.kt b/src/main/kotlin/org/eclipse/uprotocol/uuid/validate/UuidValidator.kt
index e207a75..80762b2 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/uuid/validate/UuidValidator.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/uuid/validate/UuidValidator.kt
@@ -1,24 +1,13 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
diff --git a/src/main/kotlin/org/eclipse/uprotocol/v1/UPayloadKtExt.kt b/src/main/kotlin/org/eclipse/uprotocol/v1/UPayloadKtExt.kt
deleted file mode 100644
index 0eb0c65..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/v1/UPayloadKtExt.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.eclipse.uprotocol.v1
-
-import com.google.protobuf.Any
-import com.google.protobuf.Message
-
-/**
- * Construct a UPayloadBuilder to pack google.protobuf.Message by stuffing the message into an Any.
- * @param message the message to pack
- * @return Returns the UPayloadBuilder with the configured format and value.
- */
-@JvmSynthetic
-fun UPayloadKt.Dsl.packToAny(message: Message) {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY
- value = Any.pack(message).toByteString()
-}
-
-/**
- * Construct a UPayloadBuilder to pack google.protobuf.Message using protobuf PayloadFormat.
- * @param message the message to pack
- * @return Returns the UPayloadBuilder with the configured format and value.
- */
-@JvmSynthetic
-fun UPayloadKt.Dsl.pack(message: Message) {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF
- value = message.toByteString()
-}
\ No newline at end of file
diff --git a/src/main/kotlin/org/eclipse/uprotocol/v1/UResourceKtExt.kt b/src/main/kotlin/org/eclipse/uprotocol/v1/UResourceKtExt.kt
deleted file mode 100644
index 8cbb385..0000000
--- a/src/main/kotlin/org/eclipse/uprotocol/v1/UResourceKtExt.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.eclipse.uprotocol.v1
-
-import org.eclipse.uprotocol.UServiceTopic
-
-
-/**
- * The minimum topic ID, below this value are methods.
- */
-val MIN_TOPIC_ID: Int
- @JvmSynthetic get() = 0x8000
-
-/**
- * Initializes a UResource for an RPC response.
- */
-@JvmSynthetic
-fun UResourceKt.Dsl.forRpcResponse() {
- name = "rpc"
- instance = "response"
- id = 0
-}
-
-/**
- * Initializes a UResource for an RPC request with an ID and/or a method name
- * @param method The method to be invoked.
- * @param id The ID of the request.
- */
-@JvmSynthetic
-fun UResourceKt.Dsl.forRpcRequest(method: String = instance, id: Int = this@forRpcRequest.id) {
- name = "rpc"
- if (method != instance) {
- instance = method
- }
- if (id != this@forRpcRequest.id) {
- this@forRpcRequest.id = id
- }
-}
-
-/**
- * Initializes a UResource from an ID. This method will determine if
- * the id is an RPC or topic ID based on the range
- * @param id The ID of the request.
- */
-@JvmSynthetic
-fun UResourceKt.Dsl.from(id: Int) {
- when {
- id >= MIN_TOPIC_ID -> this@from.id = id
- id > 0 -> forRpcRequest(id = id)
- id == 0 -> forRpcResponse()
- else -> {}
- }
-}
-
-/**
- * Build a UResource from a UServiceTopic that is defined in protos and
- * available from generated stubs.
- * @param topic The UServiceTopic to build the UResource from.
- * @return Returns a UResource for an RPC request.
- */
-@JvmSynthetic
-fun UResourceKt.Dsl.from(topic: UServiceTopic) {
- val nameAndInstanceParts = topic.name.split(".").dropLastWhile { it.isEmpty() }
- val resourceInstance = if (nameAndInstanceParts.size > 1) nameAndInstanceParts[1] else null
- name = nameAndInstanceParts[0]
- id = topic.id
- message = topic.message
- resourceInstance?.let { instance = it }
-}
diff --git a/src/main/kotlin/org/eclipse/uprotocol/validation/ValidationResult.kt b/src/main/kotlin/org/eclipse/uprotocol/validation/ValidationResult.kt
index 3a730d1..d44357c 100644
--- a/src/main/kotlin/org/eclipse/uprotocol/validation/ValidationResult.kt
+++ b/src/main/kotlin/org/eclipse/uprotocol/validation/ValidationResult.kt
@@ -1,24 +1,13 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2023 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
@@ -33,7 +22,6 @@ import java.util.*
* Class wrapping a ValidationResult of success or failure wrapping the value of a google.rpc.Status.
*/
sealed class ValidationResult {
-
fun isFailure(): Boolean {
return !isSuccess()
}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventAttributesTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventAttributesTest.kt
deleted file mode 100644
index c644d0a..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/datamodel/UCloudEventAttributesTest.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.cloudevent.datamodel
-
-import nl.jqno.equalsverifier.EqualsVerifier
-import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes.Companion.uCloudEventAttributes
-import org.eclipse.uprotocol.v1.UPriority
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-
-internal class UCloudEventAttributesTest {
- @Test
- @DisplayName("Make sure the equals and hash code works")
- fun testHashCodeEquals() {
- EqualsVerifier.forClass(UCloudEventAttributes::class.java).usingGetClass().verify()
- }
-
- @Test
- @DisplayName("Make sure the default toString works")
- fun testToString() {
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- traceparent = "someTraceparent"
- }
- val expected = "UCloudEventAttributes(hash=some hash, priority=UPRIORITY_CS1, ttl=3, token=someOAuthToken, traceparent=someTraceparent)"
- assertEquals(expected, uCloudEventAttributes.toString())
- }
-
- @Test @DisplayName("Test creating a valid attributes but traceparent is blank") fun test_create_valid_with_blank_traceparent() {
- val uCloudEventAttributes: UCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS6
- ttl = 3
- token = "someOAuthToken"
- traceparent = " "
- }
- assertNotNull(uCloudEventAttributes.hash)
- assertEquals("some hash", uCloudEventAttributes.hash)
- assertNotNull(uCloudEventAttributes.traceparent)
- }
-
- @Test @DisplayName("Test creating a empty attributes with only traceparent") fun test_create_empty_with_only_traceparent() {
- val uCloudEventAttributes: UCloudEventAttributes = uCloudEventAttributes {
- traceparent = "someTraceParent"
-
- }
- assertNull(uCloudEventAttributes.hash)
- assertNull(uCloudEventAttributes.priority)
- assertNull(uCloudEventAttributes.token)
- assertNull(uCloudEventAttributes.ttl)
- assertNotNull(uCloudEventAttributes.traceparent)
- assertFalse(uCloudEventAttributes.isEmpty)
- assertEquals("someTraceParent", uCloudEventAttributes.traceparent)
- }
-
- @Test
- @DisplayName("Test creating a valid attributes object")
- fun test_create_valid() {
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS6
- ttl = 3
- token = "someOAuthToken"
- traceparent = "someTraceparent"
- }
- checkNotNull(uCloudEventAttributes.hash)
- assertEquals("some hash", uCloudEventAttributes.hash)
- checkNotNull(uCloudEventAttributes.priority)
- assertEquals(UPriority.UPRIORITY_CS6, uCloudEventAttributes.priority)
- checkNotNull(uCloudEventAttributes.ttl)
- assertEquals(3, uCloudEventAttributes.ttl)
- checkNotNull(uCloudEventAttributes.token)
- assertEquals("someOAuthToken", uCloudEventAttributes.token)
- checkNotNull(uCloudEventAttributes.traceparent)
- assertEquals("someTraceparent", uCloudEventAttributes.traceparent)
- }
-
- @Test
- @DisplayName("Test the isEmpty function")
- fun test_isEmpty_function() {
- val uCloudEventAttributes: UCloudEventAttributes = UCloudEventAttributes.EMPTY
- assertTrue(uCloudEventAttributes.isEmpty)
- assertTrue(uCloudEventAttributes.hash.isNullOrBlank())
- assertNull(uCloudEventAttributes.priority)
- assertNull(uCloudEventAttributes.token)
- assertNull(uCloudEventAttributes.ttl)
- assertNull(uCloudEventAttributes.traceparent)
- }
-
- @Test
- @DisplayName("Test the isEmpty when built with blank strings function")
- fun test_isEmpty_function_when_built_with_blank_strings() {
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = " "
- token = " "
- }
- assertTrue(uCloudEventAttributes.isEmpty)
- assertNull(uCloudEventAttributes.hash)
- assertNull(uCloudEventAttributes.priority)
- assertNull(uCloudEventAttributes.token)
- assertNull(uCloudEventAttributes.ttl)
- }
-
- @Test
- @DisplayName("Test the isEmpty permutations")
- fun test_isEmpty_function_permutations() {
- val uCloudEventAttributes= uCloudEventAttributes {
- hash = " "
- token = " "
- }
- assertTrue(uCloudEventAttributes.isEmpty)
- val uCloudEventAttributes2 = uCloudEventAttributes {
- hash = "some hash"
- token = " "
- }
- assertFalse(uCloudEventAttributes2.isEmpty)
- val uCloudEventAttributes3 = uCloudEventAttributes {
- hash = " "
- token = "SomeToken"
- }
- assertFalse(uCloudEventAttributes3.isEmpty)
- val uCloudEventAttributes4 = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS0
- }
- assertFalse(uCloudEventAttributes4.isEmpty)
- val uCloudEventAttributes5 = uCloudEventAttributes {
- ttl = 8
- }
- assertFalse(uCloudEventAttributes5.isEmpty)
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.kt
deleted file mode 100644
index f4ce38c..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/factory/CloudEventFactoryTest.kt
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.cloudevent.factory
-
-import com.google.protobuf.Any
-import io.cloudevents.CloudEvent
-import io.cloudevents.core.builder.CloudEventBuilder
-import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes
-import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes.Companion.uCloudEventAttributes
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent.getCePriority
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uri.toUri
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.URI
-import java.util.*
-
-internal class CloudEventFactoryTest {
- @Test
- @DisplayName("Test create base CloudEvent")
- fun test_create_base_cloud_event() {
- val source = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- }
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "test me", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertEquals("test me", cloudEvent.id)
- assertEquals(source.value, cloudEvent.source.toString())
- assertEquals(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH), cloudEvent.type)
- assertFalse(cloudEvent.extensionNames.contains("sink"))
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS1), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertEquals("someOAuthToken", cloudEvent.getExtension("token"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create base CloudEvent with datacontenttype and dataschema")
- fun test_create_base_cloud_event_with_datacontenttype_and_schema() {
- val source = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- }
-
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "test me", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withDataContentType(DATA_CONTENT_TYPE).withDataSchema(URI.create(protoPayload.typeUrl))
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
-
- // test all attributes
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertEquals("test me", cloudEvent.id)
- assertEquals(source.value, cloudEvent.source.toString())
- assertEquals(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH), cloudEvent.type)
- assertEquals(DATA_CONTENT_TYPE, cloudEvent.dataContentType)
- assertEquals(
- "type.googleapis.com/io.cloudevents.v1.CloudEvent", Objects.requireNonNull(cloudEvent.dataSchema).toString()
- )
- assertFalse(cloudEvent.extensionNames.contains("sink"))
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS1), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertEquals("someOAuthToken", cloudEvent.getExtension("token"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create base CloudEvent without attributes")
- fun test_create_base_cloud_event_without_attributes() {
- val source = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // no additional attributes
- val uCloudEventAttributes: UCloudEventAttributes = UCloudEventAttributes.EMPTY
-
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "test me", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertEquals("test me", cloudEvent.id)
- assertEquals(source.value, cloudEvent.source.toString())
- assertEquals(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH), cloudEvent.type)
- assertFalse(cloudEvent.extensionNames.contains("sink"))
- assertFalse(cloudEvent.extensionNames.contains("hash"))
- assertFalse(cloudEvent.extensionNames.contains("priority"))
- assertFalse(cloudEvent.extensionNames.contains("ttl"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create publish CloudEvent")
- fun test_create_publish_cloud_event() {
-
- // source
- val source = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- }
- val cloudEvent: CloudEvent = CloudEventFactory.publish(source, protoPayload, uCloudEventAttributes)
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertNotNull(cloudEvent.id)
- assertEquals(source.value, cloudEvent.source.toString())
- assertEquals(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH), cloudEvent.type)
- assertFalse(cloudEvent.extensionNames.contains("sink"))
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS1), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create notification CloudEvent")
- fun test_create_notification_cloud_event() {
-
- // source
- val source = buildUriForTest()
-
- // sink
- val sink = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
- // build the cloud event of type publish with destination - a notification
- val cloudEvent: CloudEvent = CloudEventFactory.notification(source, sink, protoPayload, uCloudEventAttributes)
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertNotNull(cloudEvent.id)
- assertEquals(source.value, cloudEvent.source.toString())
- assertTrue(cloudEvent.extensionNames.contains("sink"))
- assertEquals(sink.value, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString())
- assertEquals(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH), cloudEvent.type)
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS2), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create request RPC CloudEvent coming from a local USE")
- fun test_create_request_cloud_event_from_local_use() {
-
- // UriPart for the application requesting the RPC
- val applicationUriForRPC = buildUriForTest()
-
- // service Method UriPart
- val serviceMethodUri = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- token = "someOAuthToken"
- }
- val cloudEvent: CloudEvent = CloudEventFactory.request(
- applicationUriForRPC, serviceMethodUri, protoPayload, uCloudEventAttributes
- )
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertNotNull(cloudEvent.id)
- assertEquals(applicationUriForRPC.value, cloudEvent.source.toString())
- assertTrue(cloudEvent.extensionNames.contains("sink"))
- assertEquals(serviceMethodUri.value, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString())
- assertEquals("req.v1", cloudEvent.type)
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS2), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertEquals("someOAuthToken", cloudEvent.getExtension("token"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create response RPC CloudEvent originating from a local USE")
- fun test_create_response_cloud_event_originating_from_local_use() {
-
- // UriPart for the application requesting the RPC
- val applicationUriForRPC = buildUriForTest()
-
- // service Method UriPart
- val serviceMethodUri = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
- val cloudEvent: CloudEvent = CloudEventFactory.response(
- applicationUriForRPC,
- serviceMethodUri,
- "requestIdFromRequestCloudEvent",
- protoPayload,
- uCloudEventAttributes
- )
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertNotNull(cloudEvent.id)
- assertEquals(serviceMethodUri.value, cloudEvent.source.toString())
- assertTrue(cloudEvent.extensionNames.contains("sink"))
- assertEquals(applicationUriForRPC.value, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString())
- assertEquals("res.v1", cloudEvent.type)
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS2), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertEquals("requestIdFromRequestCloudEvent", cloudEvent.getExtension("reqid"))
- assertArrayEquals(protoPayload.toByteArray(), Objects.requireNonNull(cloudEvent.data).toBytes())
- }
-
- @Test
- @DisplayName("Test create a failed response RPC CloudEvent originating from a local USE")
- fun test_create_a_failed_response_cloud_event_originating_from_local_use() {
-
- // UriPart for the application requesting the RPC
- val applicationUriForRPC = buildUriForTest()
-
- // service Method UriPart
- val serviceMethodUri = buildUriForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
- val cloudEvent: CloudEvent = CloudEventFactory.failedResponse(
- applicationUriForRPC,
- serviceMethodUri,
- "requestIdFromRequestCloudEvent",
- UCode.INVALID_ARGUMENT_VALUE,
- uCloudEventAttributes
- )
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertNotNull(cloudEvent.id)
- assertEquals(serviceMethodUri.value, cloudEvent.source.toString())
- assertTrue(cloudEvent.extensionNames.contains("sink"))
- assertEquals(applicationUriForRPC.value, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString())
- assertEquals("res.v1", cloudEvent.type)
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS2), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertEquals(UCode.INVALID_ARGUMENT_VALUE, cloudEvent.getExtension("commstatus"))
- assertEquals("requestIdFromRequestCloudEvent", cloudEvent.getExtension("reqid"))
- }
-
- @Test
- @DisplayName("Test create a failed response RPC CloudEvent originating from a microRemote USE")
- fun test_create_a_failed_response_cloud_event_originating_from_remote_use() {
-
- // UriPart for the application requesting the RPC
- val applicationUriForRPC = buildUriForTest()
-
- // service Method UriPart
- val serviceMethodUri = buildUriForTest()
-
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "some hash"
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
- val cloudEvent: CloudEvent = CloudEventFactory.failedResponse(
- applicationUriForRPC,
- serviceMethodUri,
- "requestIdFromRequestCloudEvent",
- UCode.INVALID_ARGUMENT_VALUE,
- uCloudEventAttributes
- )
- assertEquals("1.0", cloudEvent.specVersion.toString())
- assertNotNull(cloudEvent.id)
- assertEquals(serviceMethodUri.value, cloudEvent.source.toString())
- assertTrue(cloudEvent.extensionNames.contains("sink"))
- assertEquals(applicationUriForRPC.value, Objects.requireNonNull(cloudEvent.getExtension("sink")).toString())
- assertEquals("res.v1", cloudEvent.type)
- assertEquals("some hash", cloudEvent.getExtension("hash"))
- assertEquals(getCePriority(UPriority.UPRIORITY_CS2), cloudEvent.getExtension("priority"))
- assertEquals(3, cloudEvent.getExtension("ttl"))
- assertEquals(UCode.INVALID_ARGUMENT_VALUE, cloudEvent.getExtension("commstatus"))
- assertEquals("requestIdFromRequestCloudEvent", cloudEvent.getExtension("reqid"))
- }
-
- private fun buildUriForTest(): Uri {
- val uri: UUri = uUri {
- entity = uEntity { name = "body.access" }
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
- return LongUriSerializer.INSTANCE.serialize(uri).toUri()
- }
-
- private fun buildProtoPayloadForTest(): Any {
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent =
- io.cloudevents.v1.proto.CloudEvent.newBuilder().setSpecVersion("1.0").setId("hello")
- .setSource("https://example.com").setType("example.demo").setProtoData(Any.newBuilder().build()).build()
- return Any.pack(cloudEventProto)
- }
-
- companion object {
- private const val DATA_CONTENT_TYPE: String = CloudEventFactory.PROTOBUF_CONTENT_TYPE
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.kt
deleted file mode 100644
index 6bb79aa..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/factory/UCloudEventTest.kt
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.cloudevent.factory
-
-import com.google.protobuf.Any
-import com.google.protobuf.InvalidProtocolBufferException
-import io.cloudevents.CloudEvent
-import io.cloudevents.CloudEventData
-import io.cloudevents.core.builder.CloudEventBuilder
-import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes.Companion.uCloudEventAttributes
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent.getCePriority
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent.toMessage
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uri.toUri
-import org.eclipse.uprotocol.uuid.factory.UUIDV8
-import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer
-import org.eclipse.uprotocol.v1.*
-import org.eclipse.uprotocol.v1.UUID
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.URI
-import java.time.Instant
-import java.time.OffsetDateTime
-import java.time.temporal.ChronoUnit
-import java.util.*
-
-
-internal class UCloudEventTest {
- @Test
- @DisplayName("Test extracting the source from a CloudEvent.")
- fun test_extract_source_from_cloudevent() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val source: String = UCloudEvent.getSource(cloudEvent)
- assertEquals("/body.access//door.front_left#Door", source)
- }
-
- @Test
- @DisplayName("Test extracting the sink from a CloudEvent when the sink exists.")
- fun test_extract_sink_from_cloudevent_when_sink_exists() {
- val sinkForTest = "//bo.cloud/petapp/1/rpc.response"
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withExtension("sink", URI.create(sinkForTest))
- val cloudEvent: CloudEvent = builder.build()
- val sink = UCloudEvent.getSink(cloudEvent)
- assertEquals(sinkForTest, sink?.value)
- }
-
- @Test
- @DisplayName("Test extracting the sink from a CloudEvent when the sink does not exist.")
- fun test_extract_sink_from_cloudevent_when_sink_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val sink = UCloudEvent.getSink(cloudEvent)
- assertNull(sink)
- }
-
- @Test
- @DisplayName("Test extracting the request id from a CloudEvent when the request id exists.")
- fun test_extract_requestId_from_cloudevent_when_requestId_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("reqid", "someRequestId")
- val cloudEvent: CloudEvent = builder.build()
- val requestId = UCloudEvent.getRequestId(cloudEvent)
- assertEquals("someRequestId", requestId)
- }
-
- @Test
- @DisplayName("Test extracting the request id from a CloudEvent when the request id does not exist.")
- fun test_extract_requestId_from_cloudevent_when_requestId_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val requestId = UCloudEvent.getRequestId(cloudEvent)
- assertNull(requestId)
- }
-
-
- @Test
- @DisplayName("Test extracting the hash from a CloudEvent when the hash exists.")
- fun test_extract_hash_from_cloudevent_when_hash_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val hash = UCloudEvent.getHash(cloudEvent)
- assertEquals("somehash", hash)
- }
-
- @Test
- @DisplayName("Test extracting the hash from a CloudEvent when the hash does not exist.")
- fun test_extract_hash_from_cloudevent_when_hash_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("hash")
- val cloudEvent: CloudEvent = builder.build()
- val hash: String? = UCloudEvent.getHash(cloudEvent)
- assertNull(hash)
- }
-
- @Test
- @DisplayName("Test extracting the priority from a CloudEvent when the priority exists.")
- fun test_extract_priority_from_cloudevent_when_priority_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val priority = UCloudEvent.getPriority(cloudEvent)
- assertEquals(getCePriority(UPriority.UPRIORITY_CS1), priority)
- }
-
- @Test
- @DisplayName("Test extracting the priority from a CloudEvent when the priority does not exist.")
- fun test_extract_priority_from_cloudevent_when_priority_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("priority")
- val cloudEvent: CloudEvent = builder.build()
- val priority: String? = UCloudEvent.getPriority(cloudEvent)
- assertNull(priority)
-
- val message = toMessage(cloudEvent)
- assertEquals(message.attributes.priority, UPriority.UPRIORITY_UNSPECIFIED)
- }
-
- @Test
- @DisplayName("Test extracting the ttl from a CloudEvent when the ttl exists.")
- fun test_extract_ttl_from_cloudevent_when_ttl_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val ttl = UCloudEvent.getTtl(cloudEvent)
- assertEquals(3, ttl)
- }
-
- @Test
- @DisplayName("Test extracting the ttl from a CloudEvent when the ttl does not exist.")
- fun test_extract_ttl_from_cloudevent_when_ttl_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("ttl")
- val cloudEvent: CloudEvent = builder.build()
- val ttl: Int? = UCloudEvent.getTtl(cloudEvent)
- assertNull(ttl)
- }
-
- @Test
- @DisplayName("Test extracting the token from a CloudEvent when the token exists.")
- fun test_extract_token_from_cloudevent_when_token_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val token: String? = UCloudEvent.getToken(cloudEvent)
- assertEquals("someOAuthToken", token)
- }
-
- @Test
- @DisplayName("Test extracting the token from a CloudEvent when the token does not exist.")
- fun test_extract_token_from_cloudevent_when_token_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("token")
- val cloudEvent: CloudEvent = builder.build()
- val token: String? = UCloudEvent.getToken(cloudEvent)
- assertNull(token)
- }
-
- @Test
- @DisplayName("Test extracting the traceparent from a CloudEvent when the traceparent exists.")
- fun test_extract_traceparent_from_cloudevent_when_traceparent_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val traceparent: String? = UCloudEvent.getTraceparent(cloudEvent)
- assertEquals("someTraceparent", traceparent)
- }
-
- @Test
- @DisplayName("Test extracting the traceparent from a CloudEvent when the traceparent does not exist.")
- fun test_extract_traceparent_from_cloudevent_when_traceparent_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("traceparent")
- val cloudEvent: CloudEvent = builder.build()
- val traceparent: String? = UCloudEvent.getTraceparent(cloudEvent)
- assertNull(traceparent)
- }
-
-
- @Test
- @DisplayName("Test a CloudEvent has a platform communication error when the platform communication error exists.")
- fun test_cloudevent_has_platform_error_when_platform_error_exists() {
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withExtension("commstatus", UCode.ABORTED_VALUE)
- val cloudEvent: CloudEvent = builder.build()
- assertTrue(UCloudEvent.hasCommunicationStatusProblem(cloudEvent))
- assertEquals(UCode.ABORTED, UCloudEvent.getCommunicationStatus(cloudEvent))
- }
-
- @Test
- @DisplayName(
- "Test a CloudEvent has a platform communication error when the platform communication error does " + "not" + " exist."
- )
- fun test_cloudevent_has_platform_error_when_platform_error_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.hasCommunicationStatusProblem(cloudEvent))
- assertEquals(UCode.OK, UCloudEvent.getCommunicationStatus(cloudEvent))
- }
-
- @Test
- @DisplayName(
- "Test extracting the platform communication error from a CloudEvent when the platform communication " + "error exists but in the wrong format."
- )
- fun test_extract_platform_error_from_cloudevent_when_platform_error_exists_in_wrong_format() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("commstatus", "boom")
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.hasCommunicationStatusProblem(cloudEvent))
- assertEquals(UCode.OK, UCloudEvent.getCommunicationStatus(cloudEvent))
- }
-
- @Test
- @DisplayName(
- "Test extracting the platform communication error from a CloudEvent when the platform communication " + "error exists."
- )
- fun test_extract_platform_error_from_cloudevent_when_platform_error_exists() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension(
- "commstatus", UCode.INVALID_ARGUMENT_VALUE
- )
- val cloudEvent: CloudEvent = builder.build()
- val communicationStatus = UCloudEvent.getCommunicationStatus(cloudEvent)
- assertEquals(UCode.INVALID_ARGUMENT, communicationStatus)
- }
-
- @Test
- @DisplayName(
- "Test extracting the platform communication error from a CloudEvent when the platform communication " + "error does not exist."
- )
- fun test_extract_platform_error_from_cloudevent_when_platform_error_does_not_exist() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val communicationStatus = UCloudEvent.getCommunicationStatus(cloudEvent)
- assertEquals(UCode.OK, communicationStatus)
- }
-
- @Test
- @DisplayName("Test adding a platform communication error to an existing CloudEvent.")
- fun test_adding_platform_error_to_existing_cloudevent() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- assertEquals(UCode.OK, UCloudEvent.getCommunicationStatus(cloudEvent))
- val cloudEvent1: CloudEvent = UCloudEvent.addCommunicationStatus(cloudEvent, UCode.DEADLINE_EXCEEDED_VALUE)
- assertEquals(UCode.DEADLINE_EXCEEDED, UCloudEvent.getCommunicationStatus(cloudEvent1))
- assertEquals(UCode.OK, UCloudEvent.getCommunicationStatus(cloudEvent))
- }
-
- @Test
- @DisplayName("Test adding an empty platform communication error to an existing CloudEvent, does nothing.")
- fun test_adding_empty_platform_error_to_existing_cloudevent() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- assertEquals(UCode.OK, UCloudEvent.getCommunicationStatus(cloudEvent))
- val cloudEvent1: CloudEvent = UCloudEvent.addCommunicationStatus(cloudEvent, null)
- assertEquals(UCode.OK, UCloudEvent.getCommunicationStatus(cloudEvent))
- assertEquals(cloudEvent, cloudEvent1)
- }
-
- @Test
- @DisplayName("Test extracting creation timestamp from the CloudEvent UUID id when the id is not a UUIDV8.")
- fun test_extract_creation_timestamp_from_cloudevent_UUID_Id_when_not_a_UUIDV8_id() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest()
- val cloudEvent: CloudEvent = builder.build()
- val creationTimestamp = UCloudEvent.getCreationTimestamp(cloudEvent)
- assertNull(creationTimestamp)
- }
-
- @Test
- @DisplayName("Test extracting creation timestamp from the CloudEvent UUIDV8 id when the id is valid.")
- fun test_extract_creation_timestamp_from_cloudevent_UUIDV8_Id_when_UUIDV8_id_is_valid() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
-
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- val creationTimestamp = UCloudEvent.getCreationTimestamp(cloudEvent) ?: fail()
- val now: OffsetDateTime = OffsetDateTime.now()
- val creationTimestampInstant: Instant = Instant.ofEpochMilli(creationTimestamp)
- val creationTimestampInstantEpochSecond: Long = creationTimestampInstant.epochSecond
- val nowTimeStampEpochSecond: Long = now.toEpochSecond()
- assertEquals(creationTimestampInstantEpochSecond, nowTimeStampEpochSecond)
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired using creation date when no ttl is configured.")
- fun test_cloudevent_is_not_expired_cd_when_no_ttl_configured() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("ttl")
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired using creation date when configured ttl is zero.")
- fun test_cloudevent_is_not_expired_cd_when_ttl_is_zero() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", 0)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired using creation date when configured ttl is minus one.")
- fun test_cloudevent_is_not_expired_cd_when_ttl_is_minus_one() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", -1)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired using creation date when configured ttl is 500 milliseconds " + "but no creation date.")
- fun test_cloudevent_is_not_expired_cd_when_ttl_3_mili_no_creation_date() {
- val protoPayload = buildProtoPayloadForTest()
- val builder: CloudEventBuilder = CloudEventBuilder.v1().withId("id").withType("pub.v1")
- .withSource(URI.create("/body.accss//door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create(protoPayload.typeUrl)).withData(protoPayload.toByteArray())
- .withExtension("ttl", 500)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired using creation date when configured ttl is 500 milliseconds " + "with creation date of now.")
- fun test_cloudevent_is_not_expired_cd_when_ttl_500_mili_with_creation_date_of_now() {
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withTime(OffsetDateTime.now()).withExtension("ttl", 500)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName(
- "Test if the CloudEvent is expired using creation date when configured ttl is 500 milliseconds with " + "creation date of yesterday."
- )
- fun test_cloudevent_is_expired_cd_when_ttl_500_mili_with_creation_date_of_yesterday() {
- val yesterday: OffsetDateTime = OffsetDateTime.now().minus(1, ChronoUnit.DAYS)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withTime(yesterday).withExtension("ttl", 500)
- val cloudEvent: CloudEvent = builder.build()
- assertTrue(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired using creation date when configured ttl is 500 milliseconds " + "with creation date of tomorrow.")
- fun test_cloudevent_is_not_expired_cd_when_ttl_500_mili_with_creation_date_of_tomorrow() {
- val tomorrow: OffsetDateTime = OffsetDateTime.now().plus(1, ChronoUnit.DAYS)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withTime(tomorrow).withExtension("ttl", 500)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpiredByCloudEventCreationDate(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired when no ttl is configured.")
- fun test_cloudevent_is_not_expired_when_no_ttl_configured() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withoutExtension("ttl").withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired when configured ttl is zero.")
- fun test_cloudevent_is_not_expired_when_ttl_is_zero() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", 0).withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired when configured ttl is minus one.")
- fun test_cloudevent_is_not_expired_when_ttl_is_minus_one() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", -1).withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is not expired when configured ttl is large number.")
- fun test_cloudevent_is_not_expired_when_ttl_is_large_number_mili() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withExtension("ttl", Integer.MAX_VALUE).withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent is expired when configured ttl is 1 milliseconds.")
- @Throws(
- InterruptedException::class
- )
- fun test_cloudevent_is_expired_when_ttl_1_mili() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", 1).withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- Thread.sleep(800)
- assertTrue(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent isExpired when passed invalid UUID")
- fun test_cloudevent_is_expired_for_invalid_uuid() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", 50000).withId("")
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent has a UUIDV8 id.")
- fun test_cloudevent_has_a_UUIDV8_id() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- assertTrue(UCloudEvent.isCloudEventId(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent does not have a UUIDV8 id.")
- fun test_cloudevent_does_not_have_a_UUIDV8_id() {
- val uuidJava: java.util.UUID = java.util.UUID.randomUUID()
- val uuid: UUID = uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
- }
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", 3).withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isCloudEventId(cloudEvent))
- }
-
- @Test
- @DisplayName("Test if the CloudEvent does not have a valid UUID id but some string")
- fun test_cloudevent_does_not_have_a_UUID_id_just_some_string() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withExtension("ttl", 3)
- val cloudEvent: CloudEvent = builder.build()
- assertFalse(UCloudEvent.isCloudEventId(cloudEvent))
- }
-
- @Test
- @DisplayName("Test extract payload from cloud event as Any protobuf object")
- fun test_extractPayload_from_cloud_event_as_any_proto_object() {
- val payloadForCloudEvent = buildProtoPayloadForTest()
- val cloudEventData: ByteArray = payloadForCloudEvent.toByteArray()
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create(payloadForCloudEvent.typeUrl)).withData(cloudEventData)
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val extracted: Any = UCloudEvent.getPayload(cloudEvent)
- assertEquals(payloadForCloudEvent, extracted)
- }
-
- @Test
- @DisplayName("Test extract payload from cloud event when payload is not an Any protobuf object")
- @Throws(
- InvalidProtocolBufferException::class
- )
- fun test_extractPayload_from_cloud_event_when_payload_is_not_an_any_proto_object() {
- val payloadForCloudEvent: io.cloudevents.v1.proto.CloudEvent = buildProtoPayloadForTest1()
- val cloudEventData: ByteArray = payloadForCloudEvent.toByteArray()
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create("type.googleapis.com/io.cloudevents.v1.CloudEvent")).withData(cloudEventData)
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val data: CloudEventData? = cloudEvent.data
- val dataAsAny: Any = Any.parseFrom(data?.toBytes())
- val extracted: Any = UCloudEvent.getPayload(cloudEvent)
- assertEquals(dataAsAny, extracted)
- }
-
- @Test
- @DisplayName("Test extract payload from cloud event when payload is a bad protobuf object")
- fun test_extractPayload_from_cloud_event_when_payload_is_bad_proto_object() {
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create("type.googleapis.com/io.cloudevents.v1.CloudEvent"))
- .withData("
Hello
".toByteArray())
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val extracted: Any = UCloudEvent.getPayload(cloudEvent)
- assertEquals(Any.getDefaultInstance(), extracted)
- }
-
- @Test
- @DisplayName("Test extract payload from cloud event as Any protobuf object when there is no data schema")
- fun test_extractPayload_from_cloud_event_as_any_proto_object_when_no_schema() {
- val payloadForCloudEvent = buildProtoPayloadForTest()
- val cloudEventData: ByteArray = payloadForCloudEvent.toByteArray()
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withData(cloudEventData)
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val extracted: Any = UCloudEvent.getPayload(cloudEvent)
- assertEquals(payloadForCloudEvent, extracted)
- }
-
- @Test
- @DisplayName("Test extract payload from cloud event as Any protobuf object when there is no data")
- fun test_extractPayload_from_cloud_event_as_any_proto_object_when_no_data() {
- val payloadForCloudEvent = buildProtoPayloadForTest()
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create(payloadForCloudEvent.typeUrl))
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val extracted: Any = UCloudEvent.getPayload(cloudEvent)
- assertEquals(Any.getDefaultInstance(), extracted)
- }
-
- @Test
- @DisplayName("Test unpack payload by class from cloud event as protobuf Message object")
- fun test_unpack_payload_by_class_from_cloud_event_proto_message_object() {
- val payloadForCloudEvent: Any = Any.pack(
- io.cloudevents.v1.proto.CloudEvent.newBuilder().setSpecVersion("1.0").setId("hello")
- .setSource("//VCU.MY_CAR_VIN/someService").setType("example.demo")
- .setProtoData(Any.newBuilder().build()).build()
- )
- val cloudEventData: ByteArray = payloadForCloudEvent.toByteArray()
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create(payloadForCloudEvent.typeUrl)).withData(cloudEventData)
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val unpackedCE: io.cloudevents.v1.proto.CloudEvent = UCloudEvent.unpack(
- cloudEvent, io.cloudevents.v1.proto.CloudEvent::class.java
- ) ?: fail()
- assertEquals("1.0", unpackedCE.specVersion)
- assertEquals("hello", unpackedCE.id)
- assertEquals("example.demo", unpackedCE.type)
- assertEquals("//VCU.MY_CAR_VIN/someService", unpackedCE.source)
- }
-
- @Test
- @DisplayName("Test unpack payload by class from cloud event when protobuf Message is not unpack-able")
- fun test_unpack_payload_by_class_from_cloud_event_proto_message_object_when_not_valid_getMessage() {
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("someId").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left#Door")).withDataContentType(DATA_CONTENT_TYPE)
- .withDataSchema(URI.create("type.googleapis.com/io.cloudevents.v1.CloudEvent"))
- .withData("
Hello
".toByteArray())
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val extracted: io.cloudevents.v1.proto.CloudEvent? = UCloudEvent.unpack(
- cloudEvent, io.cloudevents.v1.proto.CloudEvent::class.java
- )
- assertNull(extracted)
- }
-
- @Test
- @DisplayName("Test pretty printing a cloud event with a sink")
- fun test_pretty_printing_a_cloudevent_with_a_sink() {
- val sinkForTest = "//bo.cloud/petapp/1/rpc.response"
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withExtension("sink", URI.create(sinkForTest))
- val cloudEvent: CloudEvent = builder.build()
- val prettyPrint: String = UCloudEvent.toString(cloudEvent)
- val expected =
- ("CloudEvent{id='testme', source='/body.access//door.front_left#Door', " + "sink='//bo" + ".cloud/petapp/1/rpc.response', type='pub.v1'}")
- assertEquals(expected, prettyPrint)
- }
-
- @Test
- @DisplayName("Test pretty printing a cloud event without a sink")
- fun test_pretty_printing_a_cloudevent_without_a_sink() {
- val cloudEvent: CloudEvent = buildBaseCloudEventBuilderForTest().build()
- val prettyPrint: String = UCloudEvent.toString(cloudEvent)
- val expected = "CloudEvent{id='testme', source='/body.access//door.front_left#Door', type='pub.v1'}"
- assertEquals(expected, prettyPrint)
- }
-
- @Test
- @DisplayName("Test the type for a publish message type")
- fun test_type_for_publish() {
- val uCloudEventType = UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH)
- assertEquals("pub.v1", uCloudEventType)
- }
-
-
- @Test
- @DisplayName("Test the type for a request RPC message type")
- fun test_type_for_request() {
- val uCloudEventType = UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_REQUEST)
- assertEquals("req.v1", uCloudEventType)
- }
-
- @Test
- @DisplayName("Test the type for a response RPC message type")
- fun test_type_for_response() {
- val uCloudEventType = UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE)
- assertEquals("res.v1", uCloudEventType)
- }
-
- @Test
- @DisplayName("Test the type for a unspecified message type")
- fun test_parse_publish_event_type_from_string() {
- val uCloudEventType = UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_UNSPECIFIED)
- assertTrue(uCloudEventType.isBlank())
- }
-
- @Test
- fun test_to_message_with_valid_event() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
-
- // CloudEvent
- val cloudEvent = CloudEventFactory.publish(
- buildSourceForTest(), buildProtoPayloadForTest(), uCloudEventAttributes
- )
-
- val uMessage = toMessage(cloudEvent)
- assertNotNull(uMessage)
- }
-
- @Test
- fun test_from_message_with_valid_message() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
-
- // CloudEvent
- val cloudEvent = CloudEventFactory.publish(
- buildSourceForTest(), buildProtoPayloadForTest(), uCloudEventAttributes
- )
- val uMessage = toMessage(cloudEvent)
- assertNotNull(uMessage)
- val cloudEvent1 = UCloudEvent.fromMessage(uMessage)
- assertNotNull(cloudEvent1)
- assertEquals(cloudEvent, cloudEvent1)
- }
-
- @Test
- fun test_to_from_message_from_request_cloudevent() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- token = "someOAuthToken"
- traceparent = "someTraceparent"
- }
-
- // CloudEvent
- val cloudEvent = CloudEventFactory.request(
- buildSourceForTest(),
- ("//bo.cloud/petapp/1/rpc" + ".response").toUri(),
- buildProtoPayloadForTest(),
- uCloudEventAttributes
- )
- val result = toMessage(cloudEvent)
- assertNotNull(result)
- assertEquals(UCloudEvent.getTtl(cloudEvent), result.attributes.ttl)
- assertEquals(UCloudEvent.getToken(cloudEvent), result.attributes.getToken())
- assertEquals(
- UCloudEvent.getSink(cloudEvent)?.value, LongUriSerializer.INSTANCE.serialize(result.attributes.sink)
- )
- assertEquals(UCloudEvent.getTraceparent(cloudEvent), result.attributes.traceparent)
-
- assertEquals(UCloudEvent.getPayload(cloudEvent).toByteString(), result.payload.getValue())
- assertEquals(
- UCloudEvent.getSource(cloudEvent), LongUriSerializer.INSTANCE.serialize(result.attributes.source)
- )
- assertEquals(UCloudEvent.getPriority(cloudEvent), getCePriority(result.attributes.priority))
- val cloudEvent1 = UCloudEvent.fromMessage(result)
- assertNotNull(cloudEvent1)
- assertEquals(cloudEvent, cloudEvent1)
-
- }
-
- @Test
- fun test_to_from_message_from_request_cloudevent_without_attributes() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes { }
-
- // CloudEvent
- val cloudEvent = CloudEventFactory.request(
- buildSourceForTest(), ("//bo.cloud/petapp/1/rpc.response").toUri(), buildProtoPayloadForTest(), uCloudEventAttributes
- )
- val result = toMessage(cloudEvent)
- assertNotNull(result)
- assertFalse(result.attributes.hasTtl())
- assertEquals(
- UCloudEvent.getSink(cloudEvent)?.value, LongUriSerializer.INSTANCE.serialize(result.attributes.sink)
- )
- assertEquals(UCloudEvent.getPayload(cloudEvent).toByteString(), result.payload.getValue())
- assertEquals(
- UCloudEvent.getSource(cloudEvent), LongUriSerializer.INSTANCE.serialize(result.attributes.source)
- )
- assertEquals(result.attributes.getPriority().getNumber(), 0)
- assertEquals(cloudEvent, UCloudEvent.fromMessage(result))
-
- }
-
- @Test
- fun test_to_from_message_from_response_cloudevent() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
-
- // CloudEvent
- val cloudEvent = CloudEventFactory.response(
- buildSourceForTest(),
- ("//bo.cloud/petapp/1/rpc" + ".response").toUri(),
- LongUuidSerializer.INSTANCE.serialize(UUIDV8()),
- buildProtoPayloadForTest(),
- uCloudEventAttributes
- )
- val result = toMessage(cloudEvent)
- assertNotNull(result)
- assertEquals(
- UCloudEvent.getRequestId(cloudEvent), LongUuidSerializer.INSTANCE.serialize(result.attributes.reqid)
- )
- assertEquals(UCloudEvent.getTtl(cloudEvent), result.attributes.ttl)
- assertEquals(
- UCloudEvent.getSink(cloudEvent)?.value, LongUriSerializer.INSTANCE.serialize(result.attributes.sink)
- )
- assertEquals(UCloudEvent.getPayload(cloudEvent).toByteString(), result.payload.getValue())
- assertEquals(
- UCloudEvent.getSource(cloudEvent), LongUriSerializer.INSTANCE.serialize(result.attributes.source)
- )
- assertEquals(UCloudEvent.getPriority(cloudEvent), getCePriority(result.attributes.priority))
- assertEquals(cloudEvent, UCloudEvent.fromMessage(result))
-
- }
-
- @Test
- fun test_umessage_has_platform_error_when_platform_error_exists() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
-
- val protoPayload = buildProtoPayloadForTest()
- val cloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- LongUuidSerializer.INSTANCE.serialize(
- UUIDV8()
- ), buildSourceForTest(), protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withExtension("commstatus", UCode.ABORTED_VALUE).withExtension("plevel", 2)
- val cloudEvent = cloudEventBuilder.build()
- val result = toMessage(cloudEvent)
- assertNotNull(result)
- assertEquals(UCode.ABORTED, UCloudEvent.getCommunicationStatus(cloudEvent))
- assertEquals(2, result.attributes.permissionLevel)
-
- val cloudEvent1 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent, cloudEvent1)
-
- }
-
- @Test
- fun test_to_from_message_from_cloudevent_with_all_payload_formats() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS2
- ttl = 3
- }
- val protoPayload = buildProtoPayloadForTest()
- val cloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- LongUuidSerializer.INSTANCE.serialize(
- UUIDV8()
- ), buildSourceForTest(), protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
-
- val cloudEvent = cloudEventBuilder.build()
- var result = toMessage(cloudEvent)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY, result.payload.getFormat())
-
- val cloudEvent1 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent, cloudEvent1)
- assertNull(cloudEvent1.dataContentType)
-
- val cloudEvent2 = cloudEventBuilder.withDataContentType("").build()
- result = toMessage(cloudEvent2)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY, result.payload.getFormat())
- val cloudEvent3 = UCloudEvent.fromMessage(result)
- assertNull(cloudEvent3.dataContentType)
-
- val cloudEvent4 = cloudEventBuilder.withDataContentType("application/json").build()
- result = toMessage(cloudEvent4)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_JSON, result.payload.getFormat())
- val cloudEvent5 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent4, cloudEvent5)
- assertEquals("application/json", cloudEvent5.dataContentType)
-
- val cloudEvent6 = cloudEventBuilder.withDataContentType("application/octet-stream").build()
- result = toMessage(cloudEvent6)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_RAW, result.payload.getFormat())
- val cloudEvent7 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent6, cloudEvent7)
- assertEquals("application/octet-stream", cloudEvent7.dataContentType)
-
- val cloudEvent8 = cloudEventBuilder.withDataContentType("text/plain").build()
- result = toMessage(cloudEvent8)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_TEXT, result.payload.getFormat())
- val cloudEvent9 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent8, cloudEvent9)
- assertEquals("text/plain", cloudEvent9.dataContentType)
-
- val cloudEvent10 = cloudEventBuilder.withDataContentType("application/x-someip").build()
- result = toMessage(cloudEvent10)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_SOMEIP, result.payload.getFormat())
- val cloudEvent11 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent10, cloudEvent11)
- assertEquals("application/x-someip", cloudEvent11.dataContentType)
-
- val cloudEvent12 = cloudEventBuilder.withDataContentType("application/x-someip_tlv").build()
- result = toMessage(cloudEvent12)
- assertNotNull(result)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_SOMEIP_TLV, result.payload.getFormat())
- val cloudEvent13 = UCloudEvent.fromMessage(result)
- assertEquals(cloudEvent12, cloudEvent13)
- assertEquals("application/x-someip_tlv", cloudEvent13.dataContentType)
- }
-
- @Test
- fun test_to_from_message_from_UCP_cloudevent() {
- // Additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- ttl = 3
- }
- val protoPayload = buildProtoPayloadForTest()
- val cloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- LongUuidSerializer.INSTANCE.serialize(
- UUIDV8()
- ), buildSourceForTest(), protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- cloudEventBuilder.withExtension("priority", "CS4")
- val cloudEvent = cloudEventBuilder.build()
-
- val result = toMessage(cloudEvent)
- assertNotNull(result)
- assertEquals(getCePriority(UPriority.UPRIORITY_CS4), getCePriority(result.attributes.priority))
- val cloudEvent1 = UCloudEvent.fromMessage(result)
- assertEquals(getCePriority(UPriority.UPRIORITY_CS4), UCloudEvent.getPriority(cloudEvent1))
- }
-
- private fun buildSourceForTest(): Uri {
- // source
- val uUri: UUri = uUri {
- entity = uEntity { name = "body.access" }
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
- return LongUriSerializer.INSTANCE.serialize(uUri).toUri()
- }
-
- private fun buildBaseCloudEventBuilderForTest(): CloudEventBuilder {
- // source
- val source = buildSourceForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "somehash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- traceparent = "someTraceparent"
- }
-
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "testme", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- return cloudEventBuilder
- }
-
- private fun buildProtoPayloadForTest(): Any {
- return Any.pack(buildProtoPayloadForTest1())
- }
-
- private fun buildProtoPayloadForTest1(): io.cloudevents.v1.proto.CloudEvent {
- return io.cloudevents.v1.proto.CloudEvent.newBuilder().setSpecVersion("1.0").setId("hello")
- .setSource("//VCU.MY_CAR_VIN/body.access//door.front_left#Door").setType("example.demo")
- .setProtoData(Any.newBuilder().build()).build()
- }
-
- companion object {
- private const val DATA_CONTENT_TYPE: String = CloudEventFactory.PROTOBUF_CONTENT_TYPE
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/Base64ProtobufSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/Base64ProtobufSerializerTest.kt
deleted file mode 100644
index 6078aef..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/Base64ProtobufSerializerTest.kt
+++ /dev/null
@@ -1,89 +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.cloudevent.serialize
-
-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 org.junit.jupiter.api.Assertions.*
-
-internal class Base64ProtobufSerializerTest {
- @Test
- @DisplayName("Test deserialize a byte[] to a String")
- fun test_deserialize_bytes_to_string() {
-
- // build the payload as just another cloud event packed into an Any
- val datapayload: CloudEvent = CloudEventBuilder.v1()
- .withId("hello")
- .withType("example.vertx")
- .withSource(URI.create("http://localhost"))
- .build()
- val bytes: ByteArray = CloudEventSerializers.PROTOBUF.serializer().serialize(datapayload)
- val payload: String = Base64ProtobufSerializer.deserialize(bytes)
- assertEquals("CgVoZWxsbxIQaHR0cDovL2xvY2FsaG9zdBoDMS4wIg1leGFtcGxlLnZlcnR4", payload)
- }
-
- @Test
- @DisplayName("Test deserialize a byte[] to a String when byte[] is null")
- fun test_deserialize_bytes_to_string_when_bytes_is_null() {
- val payload: String = Base64ProtobufSerializer.deserialize(null)
- assertEquals("", payload)
- }
-
- @Test
- @DisplayName("Test deserialize a byte[] to a String when byte[] is empty")
- fun test_deserialize_bytes_to_string_when_bytes_is_empty() {
- val payload: String = Base64ProtobufSerializer.deserialize(ByteArray(0))
- assertEquals("", payload)
- }
-
- @Test
- @DisplayName("Test serialize a base64 String to bytes")
- fun test_serialize_string_into_bytes() {
- val base64String = "CgVoZWxsbxIQaHR0cDovL2xvY2FsaG9zdBoDMS4wIg1leGFtcGxlLnZlcnR4"
- val bytes: ByteArray = Base64ProtobufSerializer.serialize(base64String)
- val datapayload: CloudEvent = CloudEventBuilder.v1()
- .withId("hello")
- .withType("example.vertx")
- .withSource(URI.create("http://localhost"))
- .build()
- val ceBytes: ByteArray = CloudEventSerializers.PROTOBUF.serializer().serialize(datapayload)
- assertArrayEquals(ceBytes, bytes)
- }
-
- @Test
- @DisplayName("Test serialize a base64 String to bytes when string is null")
- fun test_serialize_string_into_bytes_when_string_is_null() {
- val bytes: ByteArray = Base64ProtobufSerializer.serialize(null)
- val ceBytes = ByteArray(0)
- assertArrayEquals(ceBytes, bytes)
- }
-
- @Test
- @DisplayName("Test serialize a base64 String to bytes when string is empty")
- fun test_serialize_string_into_bytes_when_string_is_empty() {
- val bytes: ByteArray = Base64ProtobufSerializer.serialize("")
- val ceBytes = ByteArray(0)
- assertArrayEquals(ceBytes, bytes)
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.kt
deleted file mode 100644
index b58ada1..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToJsonSerializerTest.kt
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-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.factory.CloudEventFactory
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.v1.UMessageType
-import org.eclipse.uprotocol.v1.UPriority
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.URI
-import java.nio.charset.StandardCharsets
-import org.junit.jupiter.api.Assertions.*
-
-
-internal class CloudEventToJsonSerializerTest {
- private val serializer: CloudEventSerializer = CloudEventToJsonSerializer()
- private val protoContentType: String = CloudEventFactory.PROTOBUF_CONTENT_TYPE
- @Test
- @DisplayName("Test serialize a CloudEvent to JSON")
- fun test_serialize_cloud_event_to_json() {
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // cloudevent
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1()
- .withId("hello")
- .withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left"))
- .withDataContentType(protoContentType)
- .withDataSchema(URI.create(protoPayload.typeUrl))
- .withData(protoPayload.toByteArray())
- .withExtension("ttl", 3)
- .withExtension("priority", "CS1")
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val bytes: ByteArray = serializer.serialize(cloudEvent)
- val jsonString = String(bytes, StandardCharsets.UTF_8)
- val expected =
- "{\"specversion\":\"1.0\",\"id\":\"hello\",\"source\":\"/body.access/1/door.front_left\",\"type\":\"pub.v1\"," +
- "\"datacontenttype\":\"application/x-protobuf\",\"dataschema\":\"type.googleapis.com/io.cloudevents.v1.CloudEvent\"," +
- "\"priority\":\"CS1\",\"ttl\":3," +
- "\"data_base64\":\"CjB0eXBlLmdvb2dsZWFwaXMuY29tL2lvLmNsb3VkZXZlbnRzLnYxLkNsb3VkRXZlbnQSPQoFaGVsbG8SE2h0dHBzOi8vZXhhbXBsZS5jb20aAzEuMCIMZXhhbXBsZS5kZW1vKgoKA3R0bBIDGgEzQgA=\"}"
- assertEquals(expected, jsonString)
- }
-
- @Test
- @DisplayName("Test serialize and deserialize a CloudEvent to JSON")
- fun test_serialize_and_desirialize_cloud_event_to_json() {
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // cloudevent
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1()
- .withId("hello")
- .withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left"))
- .withDataContentType(protoContentType)
- .withDataSchema(URI.create(protoPayload.typeUrl))
- .withData(protoPayload.toByteArray())
- .withExtension("ttl", 3)
- .withExtension("priority", "CS1")
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val bytes: ByteArray = serializer.serialize(cloudEvent)
- val deserialize: CloudEvent = serializer.deserialize(bytes)
- assertEquals(cloudEvent, deserialize)
- }
-
- @Test
- @DisplayName("Test serialize 2 different cloud events are not the same serialized elements")
- fun test_serialize_two_different_cloud_event_are_not_the_same() {
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // cloudevent
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1()
- .withId("hello")
- .withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left"))
- .withDataContentType(protoContentType)
- .withDataSchema(URI.create(protoPayload.typeUrl))
- .withData(protoPayload.toByteArray())
- .withExtension("ttl", 3)
- .withExtension("priority", "CS1")
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
-
- // another cloudevent
- val anotherCloudEvent: CloudEvent = cloudEventBuilder
- .withType("file.v1")
- .build()
- val bytesCloudEvent: ByteArray = serializer.serialize(cloudEvent)
- val bytesAnotherCloudEvent: ByteArray = serializer.serialize(anotherCloudEvent)
- assertNotEquals(bytesCloudEvent, bytesAnotherCloudEvent)
- }
-
- @Test
- @DisplayName("Test serialize 2 equal cloud events are the same serialized elements")
- fun test_serialize_two_same_cloud_event_are_the_same() {
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // cloudevent
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1()
- .withId("hello")
- .withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left"))
- .withDataContentType(protoContentType)
- .withDataSchema(URI.create(protoPayload.typeUrl))
- .withData(protoPayload.toByteArray())
- .withExtension("ttl", 3)
- .withExtension("priority", "CS1")
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
-
- // another cloudevent
- val anotherCloudEvent: CloudEvent = cloudEventBuilder.build()
- val bytesCloudEvent: ByteArray = serializer.serialize(cloudEvent)
- val bytesAnotherCloudEvent: ByteArray = serializer.serialize(anotherCloudEvent)
- assertArrayEquals(bytesCloudEvent, bytesAnotherCloudEvent)
- }
-
- @Test
- @DisplayName("test double serialization Protobuf when creating CloudEvent with factory methods")
- @Throws(
- InvalidProtocolBufferException::class
- )
- fun test_double_serialization_protobuf_when_creating_cloud_event_with_factory_methods() {
- val serializer: CloudEventSerializer = CloudEventSerializers.JSON.serializer()
- val source = Uri("/body.access//door.front_left#Door")
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest1()
-
- // additional attributes
- val uCloudEventAttributes = UCloudEventAttributes.uCloudEventAttributes {
- hash = "somehash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- }
-
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "testme", source,
- protoPayload.toByteArray(), protoPayload.typeUrl,
- uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent1: CloudEvent = cloudEventBuilder.build()
- val bytes1: ByteArray = serializer.serialize(cloudEvent1)
- val cloudEvent2: CloudEvent = serializer.deserialize(bytes1)
- assertEquals(cloudEvent2, cloudEvent1)
- val bytes2: ByteArray = serializer.serialize(cloudEvent2)
- assertArrayEquals(bytes1, bytes2)
- val cloudEvent3: CloudEvent = serializer.deserialize(bytes2)
- val cloudEvent3Payload: Any = UCloudEvent.getPayload(cloudEvent3)
- val clazz: Class = io.cloudevents.v1.proto.CloudEvent::class.java
- assertEquals(cloudEvent3Payload.unpack(clazz), protoPayload.unpack(clazz))
- assertEquals(cloudEvent2, cloudEvent3)
- assertEquals(cloudEvent1, cloudEvent3)
- }
-
- @Test
- @DisplayName("test double serialization Json")
- @Throws(InvalidProtocolBufferException::class)
- fun test_double_serialization_json() {
- val serializer: CloudEventSerializer = CloudEventSerializers.JSON.serializer()
- val builder: CloudEventBuilder = buildCloudEventForTest()
- val cloudEventProto = buildProtoPayloadForTest1()
- builder.withDataContentType(protoContentType)
- builder.withData(cloudEventProto.toByteArray())
- builder.withDataSchema(URI.create(cloudEventProto.typeUrl))
- val cloudEvent1: CloudEvent = builder.build()
- val bytes1: ByteArray = serializer.serialize(cloudEvent1)
- val cloudEvent2: CloudEvent = serializer.deserialize(bytes1)
- assertEquals(cloudEvent2, cloudEvent1)
- val bytes2: ByteArray = serializer.serialize(cloudEvent2)
- assertArrayEquals(bytes1, bytes2)
- val cloudEvent3: CloudEvent = serializer.deserialize(bytes2)
- val cloudEvent3Payload: Any = UCloudEvent.getPayload(cloudEvent3)
- val clazz: Class = io.cloudevents.v1.proto.CloudEvent::class.java
- assertEquals(cloudEvent3Payload.unpack(clazz), cloudEventProto.unpack(clazz))
- assertEquals(cloudEvent2, cloudEvent3)
- assertEquals(cloudEvent1, cloudEvent3)
- }
-
- private fun buildCloudEventForTest(): CloudEventBuilder {
- return CloudEventBuilder.v1()
- .withId("hello")
- .withType("pub.v1")
- .withSource(URI.create("//VCU.VIN/body.access"))
- }
-
- private fun buildProtoPayloadForTest1(): Any {
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent = io.cloudevents.v1.proto.CloudEvent.newBuilder()
- .setSpecVersion("1.0")
- .setId("hello")
- .setSource("//VCU.VIN/body.access")
- .setType("pub.v1")
- .setProtoData(Any.newBuilder().build())
- .build()
- return Any.pack(cloudEventProto)
- }
-
- private fun buildProtoPayloadForTest(): Any {
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent = io.cloudevents.v1.proto.CloudEvent.newBuilder()
- .setSpecVersion("1.0")
- .setId("hello")
- .setSource("https://example.com")
- .setType("example.demo")
- .setProtoData(Any.newBuilder().build())
- .putAttributes(
- "ttl", io.cloudevents.v1.proto.CloudEvent.CloudEventAttributeValue.newBuilder()
- .setCeString("3").build()
- )
- .build()
- return Any.pack(cloudEventProto)
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.kt
deleted file mode 100644
index 66b9b23..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/serialize/CloudEventToProtobufSerializerTest.kt
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-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.factory.CloudEventFactory
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uri.toUri
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.URI
-import java.util.*
-
-
-internal class CloudEventToProtobufSerializerTest {
- private val serializer: CloudEventSerializer = CloudEventToProtobufSerializer()
- private val protoContentType: String = CloudEventFactory.PROTOBUF_CONTENT_TYPE
-
- @Test
- @DisplayName("Test serialize and deserialize a CloudEvent to protobuf")
- fun test_serialize_and_desirialize_cloud_event_to_protobuf() {
-
- // build the source
- val source = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // configure cloud event
- val uCloudEventAttributes = UCloudEventAttributes.uCloudEventAttributes {
- hash = "somehash"
- priority = UPriority.UPRIORITY_CS0
- ttl = 3
- token = "someOAuthToken"
- }
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "hello", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType("pub.v1")
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
- val bytes: ByteArray = serializer.serialize(cloudEvent)
- val deserialize: CloudEvent = serializer.deserialize(bytes)
-
- // data is not the same type, does not work -> expected data=BytesCloudEventData actual data=io.cloudevents.protobuf.ProtoDataWrapper
- //assertEquals(cloudEvent, deserialize);
- assertCloudEventsAreTheSame(cloudEvent, deserialize)
- }
-
- @Test
- @DisplayName("Test serialize 2 different cloud events are not the same serialized elements")
- fun test_serialize_two_different_cloud_event_are_not_the_same() {
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // cloudevent
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("hello").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left")).withDataContentType("application/protobuf")
- .withDataSchema(URI.create(protoPayload.typeUrl)).withData(protoPayload.toByteArray())
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
-
- // another cloudevent
- val anotherCloudEvent: CloudEvent = cloudEventBuilder.withType("file.v1").build()
- val bytesCloudEvent: ByteArray = serializer.serialize(cloudEvent)
- val bytesAnotherCloudEvent: ByteArray = serializer.serialize(anotherCloudEvent)
- assertNotEquals(bytesCloudEvent, bytesAnotherCloudEvent)
- }
-
- @Test
- @DisplayName("Test serialize 2 equal cloud events are the same serialized elements")
- fun test_serialize_two_same_cloud_event_are_the_same() {
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // cloudevent
- val cloudEventBuilder: CloudEventBuilder = CloudEventBuilder.v1().withId("hello").withType("pub.v1")
- .withSource(URI.create("/body.access/1/door.front_left")).withDataContentType("application/protobuf")
- .withDataSchema(URI.create(protoPayload.typeUrl)).withData(protoPayload.toByteArray())
- val cloudEvent: CloudEvent = cloudEventBuilder.build()
-
- // another cloudevent
- val anotherCloudEvent: CloudEvent = cloudEventBuilder.build()
- val bytesCloudEvent: ByteArray = serializer.serialize(cloudEvent)
- val bytesAnotherCloudEvent: ByteArray = serializer.serialize(anotherCloudEvent)
- assertArrayEquals(bytesCloudEvent, bytesAnotherCloudEvent)
- }
-
- @Test
- @DisplayName("test double serialization Protobuf when creating CloudEvent with factory methods")
- @Throws(
- InvalidProtocolBufferException::class
- )
- fun test_double_serialization_protobuf_when_creating_cloud_event_with_factory_methods() {
- val serializer: CloudEventSerializer = CloudEventSerializers.PROTOBUF.serializer()
-
- // source
- val source = buildUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest1()
-
- // additional attributes
- val uCloudEventAttributes = UCloudEventAttributes.uCloudEventAttributes {
- hash = "somehash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- }
-
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "testme", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(UCloudEvent.getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent1: CloudEvent = cloudEventBuilder.build()
- val bytes1: ByteArray = serializer.serialize(cloudEvent1)
- val cloudEvent2: CloudEvent = serializer.deserialize(bytes1)
- assertCloudEventsAreTheSame(cloudEvent2, cloudEvent1)
- val bytes2: ByteArray = serializer.serialize(cloudEvent2)
- assertArrayEquals(bytes1, bytes2)
- val cloudEvent3: CloudEvent = serializer.deserialize(bytes2)
- val cloudEvent3Payload: Any = UCloudEvent.getPayload(cloudEvent3)
- val clazz: Class = io.cloudevents.v1.proto.CloudEvent::class.java
- assertEquals(cloudEvent3Payload.unpack(clazz), protoPayload.unpack(clazz))
- assertEquals(cloudEvent2, cloudEvent3)
- assertCloudEventsAreTheSame(cloudEvent1, cloudEvent3)
- }
-
- @Test
- @DisplayName("test double serialization Protobuf")
- @Throws(InvalidProtocolBufferException::class)
- fun test_double_serialization_protobuf() {
- val serializer: CloudEventSerializer = CloudEventSerializers.PROTOBUF.serializer()
- val builder: CloudEventBuilder = buildCloudEventForTest()
- val cloudEventProto = buildProtoPayloadForTest1()
- builder.withDataContentType(protoContentType)
- builder.withData(cloudEventProto.toByteArray())
- builder.withDataSchema(URI.create(cloudEventProto.typeUrl))
- val cloudEvent1: CloudEvent = builder.build()
- val bytes1: ByteArray = serializer.serialize(cloudEvent1)
- val cloudEvent2: CloudEvent = serializer.deserialize(bytes1)
- assertCloudEventsAreTheSame(cloudEvent2, cloudEvent1)
- val bytes2: ByteArray = serializer.serialize(cloudEvent2)
- assertArrayEquals(bytes1, bytes2)
- val cloudEvent3: CloudEvent = serializer.deserialize(bytes2)
- val cloudEvent3Payload: Any = UCloudEvent.getPayload(cloudEvent3)
- val clazz: Class = io.cloudevents.v1.proto.CloudEvent::class.java
- assertEquals(cloudEvent3Payload.unpack(clazz), cloudEventProto.unpack(clazz))
- assertEquals(cloudEvent2, cloudEvent3)
- assertCloudEventsAreTheSame(cloudEvent1, cloudEvent3)
- }
-
- @Test
- @DisplayName("test double serialization proto to Json")
- fun test_double_serialization_proto_to_json() {
- val protoSerializer: CloudEventSerializer = CloudEventSerializers.PROTOBUF.serializer()
- val jsonSerializer: CloudEventSerializer = CloudEventSerializers.JSON.serializer()
- val builder: CloudEventBuilder = buildCloudEventForTest()
- val cloudEventProto = buildProtoPayloadForTest1()
- builder.withDataContentType(protoContentType)
- builder.withData(cloudEventProto.toByteArray())
- builder.withDataSchema(URI.create(cloudEventProto.typeUrl))
- val cloudEvent1: CloudEvent = builder.build()
- val bytes1: ByteArray = protoSerializer.serialize(cloudEvent1)
- val cloudEvent2: CloudEvent = protoSerializer.deserialize(bytes1)
- assertCloudEventsAreTheSame(cloudEvent2, cloudEvent1)
- val bytes2: ByteArray = protoSerializer.serialize(cloudEvent2)
- assertArrayEquals(bytes1, bytes2)
- val bytes3: ByteArray = jsonSerializer.serialize(cloudEvent2)
- val cloudEvent3: CloudEvent = jsonSerializer.deserialize(bytes3)
- assertCloudEventsAreTheSame(cloudEvent2, cloudEvent3)
- assertEquals(cloudEvent1, cloudEvent3)
- }
-
- @Test
- @DisplayName("test double serialization json to proto")
- fun test_double_serialization_json_to_proto() {
- val protoSerializer: CloudEventSerializer = CloudEventSerializers.PROTOBUF.serializer()
- val jsonSerializer: CloudEventSerializer = CloudEventSerializers.JSON.serializer()
- val builder: CloudEventBuilder = buildCloudEventForTest()
- val cloudEventProto = buildProtoPayloadForTest1()
- builder.withDataContentType(protoContentType)
- builder.withData(cloudEventProto.toByteArray())
- builder.withDataSchema(URI.create(cloudEventProto.typeUrl))
- val cloudEvent1: CloudEvent = builder.build()
- val bytes1: ByteArray = jsonSerializer.serialize(cloudEvent1)
- val cloudEvent2: CloudEvent = jsonSerializer.deserialize(bytes1)
- assertEquals(cloudEvent2, cloudEvent1)
- val bytes2: ByteArray = jsonSerializer.serialize(cloudEvent2)
- assertArrayEquals(bytes1, bytes2)
- val bytes3: ByteArray = protoSerializer.serialize(cloudEvent2)
- val cloudEvent3: CloudEvent = protoSerializer.deserialize(bytes3)
- assertCloudEventsAreTheSame(cloudEvent2, cloudEvent3)
- assertCloudEventsAreTheSame(cloudEvent1, cloudEvent3)
- }
-
- private fun assertCloudEventsAreTheSame(cloudEvent1: CloudEvent, cloudEvent2: CloudEvent) {
- assertNotNull(cloudEvent1)
- assertNotNull(cloudEvent2)
- assertEquals(cloudEvent1.specVersion.toString(), cloudEvent2.specVersion.toString())
- assertEquals(cloudEvent1.id, cloudEvent2.id)
- assertEquals(cloudEvent1.source, cloudEvent2.source)
- assertEquals(cloudEvent1.type, cloudEvent2.type)
- assertEquals(cloudEvent1.dataContentType, cloudEvent2.dataContentType)
- assertEquals(cloudEvent1.dataSchema, cloudEvent2.dataSchema)
- val ce1ExtensionNames: Set = cloudEvent1.extensionNames
- val ce2ExtensionNames: Set = cloudEvent2.extensionNames
- assertEquals(ce1ExtensionNames.joinToString(","), ce2ExtensionNames.joinToString(","))
- assertArrayEquals(
- Objects.requireNonNull(cloudEvent1.data).toBytes(), Objects.requireNonNull(cloudEvent2.data).toBytes()
- )
- assertEquals(cloudEvent1, cloudEvent2)
- }
-
- private fun buildCloudEventForTest(): CloudEventBuilder {
- return CloudEventBuilder.v1().withId("hello").withType("pub.v1").withSource(URI.create("//VCU.VIN/body.access"))
- }
-
- private fun buildProtoPayloadForTest1(): Any {
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent =
- io.cloudevents.v1.proto.CloudEvent.newBuilder().setSpecVersion("1.0").setId("hello")
- .setSource("//VCU.VIN/body.access").setType("pub.v1").setProtoData(Any.newBuilder().build()).build()
- return Any.pack(cloudEventProto)
- }
-
- private fun buildUriForTest(): Uri {
- val uri: UUri = uUri {
- entity = uEntity { name = "body.access" }
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
-
- return LongUriSerializer.INSTANCE.serialize(uri).toUri()
- }
-
- private fun buildProtoPayloadForTest(): Any {
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent =
- io.cloudevents.v1.proto.CloudEvent.newBuilder().setSpecVersion("1.0").setId("hello")
- .setSource("https://example.com").setType("example.demo").setProtoData(Any.newBuilder().build())
- .putAttributes(
- "ttl",
- io.cloudevents.v1.proto.CloudEvent.CloudEventAttributeValue.newBuilder().setCeString("3").build()
- ).build()
- return Any.pack(cloudEventProto)
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.kt
deleted file mode 100644
index 5f3f75b..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/validate/CloudEventValidatorTest.kt
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.cloudevent.validate
-
-import com.google.protobuf.Any
-import io.cloudevents.CloudEvent
-import io.cloudevents.core.builder.CloudEventBuilder
-import org.eclipse.uprotocol.cloudevent.datamodel.UCloudEventAttributes.Companion.uCloudEventAttributes
-import org.eclipse.uprotocol.cloudevent.factory.CloudEventFactory
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent
-import org.eclipse.uprotocol.cloudevent.factory.UCloudEvent.getEventType
-import org.eclipse.uprotocol.cloudevent.validate.CloudEventValidator.Companion.getValidator
-import org.eclipse.uprotocol.uri.Uri
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uri.toUri
-import org.eclipse.uprotocol.uuid.factory.UUIDV6
-import org.eclipse.uprotocol.uuid.factory.UUIDV8
-import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer
-import org.eclipse.uprotocol.v1.*
-import org.eclipse.uprotocol.validation.ValidationResult
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.URI
-import java.time.Instant
-
-
-internal class CloudEventValidatorTest {
- @Test
- @DisplayName("Test get a publish cloud event validator")
- fun test_get_a_publish_cloud_event_validator() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("pub.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = cloudEvent.getValidator()
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- assertEquals("CloudEventValidator.Publish", validator.toString())
- }
-
- @Test
- @DisplayName("Test get a notification cloud event validator")
- fun test_get_a_notification_cloud_event_validator() {
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withExtension("sink", "//bo.cloud/petapp").withType("not.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Notification
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- assertEquals("CloudEventValidator.Notification", validator.toString())
- }
-
- @Test
- @DisplayName("Test publish cloud event type")
- fun test_publish_cloud_event_type() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("res.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals(
- "Invalid CloudEvent type [res.v1]. CloudEvent of type Publish must have a type of 'pub.v1'", status.message
- )
- }
-
- @Test
- @DisplayName("Test notification cloud event type")
- fun test_notification_cloud_event_type() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("res.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Notification
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals(
- "Invalid CloudEvent type [res.v1]. CloudEvent of type Notification must have a type of 'not.v1'", status.message
- )
- }
-
- @Test
- @DisplayName("Test get a request cloud event validator")
- fun test_get_a_request_cloud_event_validator() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("req.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = cloudEvent.getValidator()
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- assertEquals("CloudEventValidator.Request", validator.toString())
- }
-
- @Test
- @DisplayName("Test request cloud event type")
- fun test_request_cloud_event_type() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("pub.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Request
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals(
- "Invalid CloudEvent type [pub.v1]. CloudEvent of type Request must have a type of 'req.v1'", status.message
- )
- }
-
- @Test
- @DisplayName("Test get a response cloud event validator")
- fun test_get_a_response_cloud_event_validator() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("res.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = cloudEvent.getValidator()
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- assertEquals("CloudEventValidator.Response", validator.toString())
- }
-
- @Test
- @DisplayName("Test response cloud event type")
- fun test_response_cloud_event_type() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("pub.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Response
- val status: UStatus = validator.validateType(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals(
- "Invalid CloudEvent type [pub.v1]. CloudEvent of type Response must have a type of 'res.v1'", status.message
- )
- }
-
- @Test
- @DisplayName("Test get a publish cloud event validator when cloud event type is unknown")
- fun test_get_a_publish_cloud_event_validator_when_cloud_event_type_is_unknown() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withType("lala.v1")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = cloudEvent.getValidator()
- assertEquals("CloudEventValidator.Publish", validator.toString())
- }
-
- @Test
- @DisplayName("Test validate version")
- fun validate_cloud_event_version_when_valid() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- val status: UStatus = CloudEventValidator.validateVersion(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- }
-
- @Test
- @DisplayName("Test validate version when not valid")
- fun validate_cloud_event_version_when_not_valid() {
- val payloadForTest = buildProtoPayloadForTest()
- val builder: CloudEventBuilder =
- CloudEventBuilder.v03().withId("id").withType("pub.v1").withSource(URI.create("/body.access"))
- .withDataContentType("application/protobuf").withDataSchema(URI.create(payloadForTest.typeUrl))
- .withData(payloadForTest.toByteArray())
- val cloudEvent: CloudEvent = builder.build()
- val status: UStatus = CloudEventValidator.validateVersion(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals("Invalid CloudEvent version [0.3]. CloudEvent version must be 1.0.", status.message)
- }
-
- @Test
- @DisplayName("Test validate cloudevent id when valid")
- fun validate_cloud_event_id_when_valid() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- val status: UStatus = CloudEventValidator.validateId(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- }
-
- @Test
- @DisplayName("Test validate cloudevent id when not UUIDv8 type id")
- fun validate_cloud_event_id_when_not_uuidv6_type_id() {
- val uuidJava: java.util.UUID = java.util.UUID.randomUUID()
- val uuid: UUID = uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
- }
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withId(strUuid)
- val cloudEvent: CloudEvent = builder.build()
- val status: UStatus = CloudEventValidator.validateId(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals(
- "Invalid CloudEvent Id [$strUuid]. CloudEvent Id must be of type UUIDv8.", status.message
- )
- }
-
- @Test
- @DisplayName("Test validate cloudevent id when not valid")
- fun validate_cloud_event_id_when_not_valid() {
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- .withId("testme")
- val cloudEvent: CloudEvent = builder.build()
- val status: UStatus = CloudEventValidator.validateId(cloudEvent).toStatus()
- assertEquals(UCode.INVALID_ARGUMENT, status.code)
- assertEquals("Invalid CloudEvent Id [testme]. CloudEvent Id must be of type UUIDv8.", status.message)
- }
-
- @Test
- @DisplayName("Test local Publish type CloudEvent is valid everything is valid")
- fun test_publish_type_cloudevent_is_valid_when_everything_is_valid_local() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("/body.access/1/door.front_left#Door"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(ValidationResult.success(), result)
- }
-
- @Test
- @DisplayName("Test microRemote Publish type CloudEvent is valid everything is valid")
- fun test_publish_type_cloudevent_is_valid_when_everything_is_valid_remote() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//VCU.myvin/body.access/1/door.front_left#Door"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(ValidationResult.success(), result)
- }
-
- @Test
- @DisplayName("Test microRemote Publish type CloudEvent is valid everything is valid with a sink")
- fun test_publish_type_cloudevent_is_valid_when_everything_is_valid_remote_with_a_sink() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//VCU.myvin/body.access/1/door.front_left#Door"))
- .withExtension("sink", "//bo.cloud/petapp")
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(ValidationResult.success(), result)
- }
-
- @Test
- @DisplayName("Test microRemote Publish type CloudEvent is not valid everything is valid with invalid sink")
- fun test_publish_type_cloudevent_is_not_valid_when_remote_with_invalid_sink() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//VCU.myvin/body.access/1/door.front_left#Door"))
- .withExtension("sink", "//bo.cloud").withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.", result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Publish type CloudEvent is not valid when source is empty")
- fun test_publish_type_cloudevent_is_not_valid_when_source_is_empty() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid).withSource(URI.create("/"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals("Invalid Publish type CloudEvent source [/]. Uri is empty.", result.getMessage())
- }
-
- @Test
- @DisplayName("Test Notification type CloudEvent is not valid when source is empty")
- fun test_notification_type_cloudevent_is_not_valid_when_source_is_empty() {
- val strUUID: String = LongUuidSerializer.INSTANCE.serialize(UUIDV8())
- val cloudEvent = buildBaseCloudEventBuilderForTest().withId(strUUID)
- .withSource(URI.create("/")).withType(getEventType(UMessageType.UMESSAGE_TYPE_NOTIFICATION)).build()
- val validator: CloudEventValidator = Notification
- val result = validator.validate(cloudEvent)
- assertEquals(
- "Invalid Notification type CloudEvent source [/]. Uri is empty.,Invalid CloudEvent sink. Notification CloudEvent sink must be an uri.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Publish type CloudEvent is not valid when source is invalid and id invalid")
- fun test_publish_type_cloudevent_is_not_valid_when_source_is_missing_authority() {
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withId("testme").withSource(URI.create("/body.access"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid CloudEvent Id [testme]. CloudEvent Id must be of type UUIDv8.," + "Invalid Publish type " + "CloudEvent source [/body.access]. UriPart is missing uResource name.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Publish type CloudEvent is not valid when source is invalid missing message information")
- fun test_publish_type_cloudevent_is_not_valid_when_source_is_missing_message_info() {
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId("testme")
- .withSource(URI.create("/body.access/1/door.front_left"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid CloudEvent Id [testme]. CloudEvent Id must be of type UUIDv8.," + "Invalid Publish type " + "CloudEvent source [/body.access/1/door.front_left]. UriPart is missing Message information.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Notification type CloudEvent is valid everything is valid")
- fun test_notification_type_cloudevent_is_valid_when_everything_is_valid() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("/body.access/1/door.front_left#Door"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_NOTIFICATION))
- .withExtension("sink", "//bo.cloud/petapp")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Notification
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(ValidationResult.success(), result)
- }
-
- @Test
- @DisplayName("Test Notification type CloudEvent is not valid missing sink")
- fun test_notification_type_cloudevent_is_not_valid_missing_sink() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("/body.access/1/door.front_left#Door"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_NOTIFICATION))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Notification
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals("Invalid CloudEvent sink. Notification CloudEvent sink must be an uri.", result.getMessage())
- }
-
- @Test
- @DisplayName("Test Notification type CloudEvent is not valid invalid sink")
- fun test_notification_type_cloudevent_is_not_valid_invalid_sink() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("/body.access/1/door.front_left#Door"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_NOTIFICATION)).withExtension("sink", "//bo.cloud")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Notification
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid Notification type CloudEvent sink [//bo.cloud]. Uri is missing uSoftware Entity name.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Request type CloudEvent is valid everything is valid")
- fun test_request_type_cloudevent_is_valid_when_everything_is_valid() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//bo.cloud/petapp//rpc.response"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_REQUEST))
- .withExtension("sink", "//VCU.myvin/body.access/1/rpc.UpdateDoor")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Request
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(ValidationResult.success(), result)
- }
-
- @Test
- @DisplayName("Test Request type CloudEvent is not valid invalid source")
- fun test_request_type_cloudevent_is_not_valid_invalid_source() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withId(strUuid).withSource(URI.create("//bo.cloud/petapp//dog"))
- .withExtension("sink", "//VCU.myvin/body.access/1/rpc.UpdateDoor")
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_REQUEST))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Request
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid RPC Request CloudEvent source [//bo.cloud/petapp//dog]. " + "Invalid RPC uri application " + "response topic. UriPart is missing rpc.response.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Request type CloudEvent is not valid missing sink")
- fun test_request_type_cloudevent_is_not_valid_missing_sink() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//bo.cloud/petapp//rpc.response"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_REQUEST))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Request
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid RPC Request CloudEvent sink. Request CloudEvent sink must be uri for the method to be called.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Request type CloudEvent is not valid sink not rpc command")
- fun test_request_type_cloudevent_is_not_valid_invalid_sink_not_rpc_command() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//bo.cloud/petapp//rpc.response"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_REQUEST))
- .withExtension("sink", "//VCU.myvin/body.access/1/UpdateDoor")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Request
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid RPC Request CloudEvent sink [//VCU.myvin/body.access/1/UpdateDoor]. " + "Invalid RPC method " + "uri. UriPart should be the method to be called, or method from response.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Response type CloudEvent is valid everything is valid")
- fun test_response_type_cloudevent_is_valid_when_everything_is_valid() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//VCU.myvin/body.access/1/rpc.UpdateDoor"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- .withExtension("sink", "//bo.cloud/petapp//rpc.response")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Response
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(ValidationResult.success(), result)
- }
-
- @Test
- @DisplayName("Test Response type CloudEvent is not valid invalid source")
- fun test_response_type_cloudevent_is_not_valid_invalid_source() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//VCU.myvin/body.access/1/UpdateDoor"))
- .withExtension("sink", "//bo.cloud/petapp//rpc.response")
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Response
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid RPC Response CloudEvent source [//VCU.myvin/body.access/1/UpdateDoor]. " + "Invalid RPC " + "method uri. UriPart should be the method to be called, or method from response.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Response type CloudEvent is not valid missing sink and invalid source")
- fun test_response_type_cloudevent_is_not_valid_missing_sink_and_invalid_source() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withSource(URI.create("//VCU.myvin/body.access/1/UpdateDoor"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Response
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid RPC Response CloudEvent source [//VCU.myvin/body.access/1/UpdateDoor]. " + "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.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Response type CloudEvent is not valid sink and source, missing entity name.")
- fun test_response_type_cloudevent_is_not_valid_invalid_sink() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder = buildBaseCloudEventBuilderForTest().withId(strUuid)
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- .withSource(URI.create("//VCU.myvin")).withExtension("sink", "//bo.cloud")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Response
- val result: ValidationResult = validator.validate(cloudEvent)
- assertEquals(
- "Invalid RPC Response CloudEvent source [//VCU.myvin]. Invalid RPC method uri. Uri is missing " + "uSoftware Entity name.,Invalid RPC Response CloudEvent sink [//bo.cloud]. Invalid RPC uri " + "application response topic. Uri is missing uSoftware Entity name.",
- result.getMessage()
- )
- }
-
- @Test
- @DisplayName("Test Response type CloudEvent is not valid source not rpc command")
- fun test_response_type_cloudevent_is_not_valid_invalid_source_not_rpc_command() {
- val uuid: UUID = UUIDV8()
- val strUuid = LongUuidSerializer.INSTANCE.serialize(uuid)
- val builder: CloudEventBuilder =
- buildBaseCloudEventBuilderForTest().withId(strUuid).withSource(URI.create("//bo.cloud/petapp/1/dog"))
- .withType(getEventType(UMessageType.UMESSAGE_TYPE_RESPONSE))
- .withExtension("sink", "//VCU.myvin/body.access/1/UpdateDoor")
- val cloudEvent: CloudEvent = builder.build()
- val validator: CloudEventValidator = Response
- val result: ValidationResult = validator.validate(cloudEvent)
- 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. UriPart is missing rpc.response.",
- result.getMessage()
- )
- }
-
- private fun buildBaseCloudEventBuilderForTest(): CloudEventBuilder {
- // source
- val source = buildLongUriForTest()
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
-
- // additional attributes
- val uCloudEventAttributes = uCloudEventAttributes {
- hash = "somehash"
- priority = UPriority.UPRIORITY_CS1
- ttl = 3
- token = "someOAuthToken"
- }
- // build the cloud event
- val cloudEventBuilder: CloudEventBuilder = CloudEventFactory.buildBaseCloudEvent(
- "testme", source, protoPayload.toByteArray(), protoPayload.typeUrl, uCloudEventAttributes
- )
- cloudEventBuilder.withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH))
- return cloudEventBuilder
- }
-
- private fun buildProtoPayloadForTest(): Any {
- val cloudEventProto: io.cloudevents.v1.proto.CloudEvent =
- io.cloudevents.v1.proto.CloudEvent.newBuilder().setSpecVersion("1.0").setId("hello")
- .setSource("/body.access").setType("example.demo").setProtoData(Any.newBuilder().build()).build()
- return Any.pack(cloudEventProto)
- }
-
- @Test
- @DisplayName("Test create a v6 Cloudevent and validate it works with this SDK")
- fun test_create_a_v6_cloudevent_and_validate_it_against_sdk() {
-
- // source
- val source = buildLongUriForTest()
- val uuid: UUID = UUIDV6()
- val id = LongUuidSerializer.INSTANCE.serialize(uuid)
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
- val attributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS0
- ttl = 1000
- }
-
- // build the cloud event
- val cloudEvent: CloudEvent = CloudEventFactory.buildBaseCloudEvent(
- id, source, protoPayload.toByteArray(), protoPayload.typeUrl, attributes
- ).withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH)).build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertTrue(result.isSuccess())
- assertFalse(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test create an expired v6 Cloudevent to ensure we report the expiration")
- fun test_create_an_expired_v6_cloudevent() {
-
- // source
- val source = buildLongUriForTest()
- val uuid: UUID = UUIDV6(Instant.now().minusSeconds(100))
- val id = LongUuidSerializer.INSTANCE.serialize(uuid)
-
- // fake payload
- val protoPayload = buildProtoPayloadForTest()
- val attributes = uCloudEventAttributes {
- priority = UPriority.UPRIORITY_CS0
- ttl = 1000
- }
-
- // build the cloud event
- val cloudEvent: CloudEvent = CloudEventFactory.buildBaseCloudEvent(
- id, source, protoPayload.toByteArray(), protoPayload.typeUrl, attributes
- ).withType(getEventType(UMessageType.UMESSAGE_TYPE_PUBLISH)).build()
- val validator: CloudEventValidator = Publish
- val result: ValidationResult = validator.validate(cloudEvent)
- assertTrue(result.isSuccess())
- assertTrue(UCloudEvent.isExpired(cloudEvent))
- }
-
- @Test
- @DisplayName("Test fetching the notification validator")
- fun test_fetching_the_notification_validator() {
- val cloudEvent = buildBaseCloudEventBuilderForTest().withType(getEventType(UMessageType.UMESSAGE_TYPE_NOTIFICATION)).build()
- val validator: CloudEventValidator = cloudEvent.getValidator()
- val status = validator.validateType(cloudEvent).toStatus()
- assertEquals(status, ValidationResult.STATUS_SUCCESS)
- assertEquals("CloudEventValidator.Notification", validator.toString())
- }
-
- private fun buildLongUriForTest(): Uri {
- return LongUriSerializer.INSTANCE.serialize(buildUUriForTest()).toUri()
- }
-
- private fun buildUUriForTest(): UUri {
- return uUri {
- entity = uEntity { name = "body.access" }
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.kt b/src/test/kotlin/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.kt
deleted file mode 100644
index 7ee5629..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/cloudevent/validate/ValidationResultTest.kt
+++ /dev/null
@@ -1,92 +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.cloudevent.validate
-
-
-import org.eclipse.uprotocol.v1.UCode
-import org.eclipse.uprotocol.v1.UStatus
-import org.eclipse.uprotocol.v1.uStatus
-import org.eclipse.uprotocol.validation.ValidationResult
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-
-internal class ValidationResultTest {
- @Test
- @DisplayName("Test success validation result to string")
- fun test_success_validation_result_toString() {
- val success: ValidationResult = ValidationResult.success()
- assertEquals("ValidationResult.Success()", success.toString())
- }
-
- @Test
- @DisplayName("Test failure validation result to string")
- fun test_failure_validation_result_toString() {
- val failure: ValidationResult = ValidationResult.failure("boom")
- assertEquals("ValidationResult.Failure(message='boom')", failure.toString())
- }
-
- @Test
- @DisplayName("Test success validation result isSuccess")
- fun test_success_validation_result_isSuccess() {
- val success: ValidationResult = ValidationResult.success()
- assertTrue(success.isSuccess())
- }
-
- @Test
- @DisplayName("Test failure validation result isSuccess")
- fun test_failure_validation_result_isSuccess() {
- val failure: ValidationResult = ValidationResult.failure("boom")
- assertFalse(failure.isSuccess())
- }
-
- @Test
- @DisplayName("Test success message")
- fun test_success_validation_result_getMessage() {
- val success: ValidationResult = ValidationResult.success()
- assertTrue(success.getMessage().isBlank())
- }
-
- @Test
- @DisplayName("Test failure message")
- fun test_failure_validation_result_getMessage() {
- val failure: ValidationResult = ValidationResult.failure("boom")
- assertEquals("boom", failure.getMessage())
- }
-
- @Test
- @DisplayName("Test success toStatus")
- fun test_success_validation_result_toStatus() {
- val success: ValidationResult = ValidationResult.success()
- assertEquals(ValidationResult.STATUS_SUCCESS, success.toStatus())
- }
-
- @Test
- @DisplayName("Test failure toStatus")
- fun test_failure_validation_result_toStatus() {
- val failure: ValidationResult = ValidationResult.failure("boom")
- val status: UStatus = uStatus {
- code = UCode.INVALID_ARGUMENT
- message = "boom"
- }
- assertEquals(status, failure.toStatus())
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/rpc/CallOptionsTest.kt b/src/test/kotlin/org/eclipse/uprotocol/rpc/CallOptionsTest.kt
deleted file mode 100644
index f153207..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/rpc/CallOptionsTest.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.eclipse.uprotocol.rpc
-
-import org.eclipse.uprotocol.v1.callOptions
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-
-class CallOptionsTest {
- @Test
- @DisplayName("Make sure the toString works")
- fun testToString() {
- val callOptions = callOptions {
- ttl = 30
- token = "someToken"
- }
- val expected = "ttl: 30\ntoken: \"someToken\"\n"
- assertEquals(expected, callOptions.toString())
- }
-
- @Test
- @DisplayName("Test creating CallOptions with only a token")
- fun testCreatingCallOptionsWithAToken() {
- val callOptions = callOptions {
- token = "someToken"
- }
- assertTrue(callOptions.token.isNotEmpty())
- assertEquals("someToken", callOptions.token)
- }
-
-
- @Test
- @DisplayName("Test creating CallOptions with only an empty string token")
- fun testCreatingCallOptionsWithAnEmptyStringToken() {
- val callOptions = callOptions {
- token = ""
- }
- assertTrue(callOptions.token.isEmpty())
- }
-
- @Test
- @DisplayName("Test creating CallOptions with only a token with only spaces")
- fun testCreatingCallOptionsWithATokenWithOnlySpaces() {
- val callOptions = callOptions {
- token = " "
- }
- assertTrue(callOptions.token.isBlank())
- }
-
- @Test
- @DisplayName("Test creating CallOptions with only a timeout")
- fun testCreatingCallOptionsWithATimeout() {
- val callOptions = callOptions {
- ttl = 30
- }
- assertEquals(30, callOptions.ttl)
- assertTrue(callOptions.token.isEmpty())
- }
-}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/rpc/RpcTest.kt b/src/test/kotlin/org/eclipse/uprotocol/rpc/RpcTest.kt
deleted file mode 100644
index 3eb521f..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/rpc/RpcTest.kt
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.rpc
-
-
-import com.google.protobuf.Any
-import com.google.protobuf.Int32Value
-import com.google.protobuf.kotlin.toByteString
-import io.cloudevents.v1.proto.CloudEvent
-import kotlinx.coroutines.flow.*
-import kotlinx.coroutines.test.runTest
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.util.concurrent.CompletionException
-import kotlin.test.fail
-
-
-internal class RpcTest {
- private var returnsNumber3: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- return flowOf(uMessage {
- payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF
- value = Any.pack(Int32Value.of(3)).toByteString()
- }
- })
- }
- }
- private var happyPath: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- return flowOf(testUMessage)
- }
- }
- private var withStatusCodeInsteadOfHappyPath: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- val status: UStatus = uStatus {
- code = UCode.INVALID_ARGUMENT
- message = "boom"
- }
- val any: Any = Any.pack(status)
- return flowOf(uMessage {
- payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF
- value = any.toByteString()
- }
- })
- }
- }
- private var withStatusCodeHappyPath: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- val status: UStatus = uStatus {
- code = UCode.OK
- message = "all good"
- }
- val any: Any = Any.pack(status)
- return flowOf(uMessage {
- payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF
- value = any.toByteString()
- }
- })
- }
- }
- private var thatBarfsCrapyPayload: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- return flowOf(uMessage {
- payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_RAW
- value = byteArrayOf(0).toByteString()
- }
- })
- }
- }
- private var thatFlowWithAnException: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- return flow {
- throw RuntimeException("Boom")
- }
- }
- }
- private var thatReturnsTheWrongProto: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- val any: Any = Any.pack(Int32Value.of(42))
- return flowOf(uMessage {
- payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF
- value = any.toByteString()
- }
- })
- }
- }
-
- private var thatReturnsUMessageWithoutPayload: RpcClient = object : RpcClient {
- override fun invokeMethod(methodUri: UUri, requestPayload: UPayload, options: CallOptions): Flow {
- return flowOf(uMessage {
- })
- }
- }
-
- @Test
- fun test_compose_happy_path() = runTest {
- val payload: UPayload = buildUPayload()
- returnsNumber3.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResponse().map {
- Int32Value.of(it.value + 5)
- }.first().run {
- assertEquals(Int32Value.of(8), this)
- }
- }
-
- @Test
- fun test_compose_that_returns_status() = runTest {
- val payload: UPayload = buildUPayload()
- try {
- withStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResponse().map {
- Int32Value.of(it.value + 5)
- }.first()
- fail("should not reach here")
- } catch (e: Exception) {
- assertThrows(RuntimeException::class.java) {
- throw e
- }
- }
- }
-
- @Test
- fun test_success_invoke_method_happy_flow_using_toResponse() = runTest {
- val payload: UPayload = buildUPayload()
- happyPath.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResponse().first().run {
- assertEquals(buildCloudEvent(), this)
- }
- }
-
- @Test
- fun test_fail_invoke_method_when_invoke_method_returns_a_status_using_toResponse() = runTest {
- val payload: UPayload = buildUPayload()
- try {
- withStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResponse().first()
- fail("should not reach here")
- } catch (e: Exception) {
- assertThrows(RuntimeException::class.java) {
- throw e
- }
- assertEquals(
- "Unknown payload type [type.googleapis.com/uprotocol.v1.UStatus]. Expected " + "[io.cloudevents.v1.proto.CloudEvent]",
- e.message,
- )
- }
- }
-
- @Test
- fun test_fail_invoke_method_when_invoke_method_threw_an_exception_using_toResponse() = runTest {
- val payload: UPayload = buildUPayload()
- try {
- thatFlowWithAnException.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResponse().first()
- fail("should not reach here")
- } catch (e: Exception) {
- assertThrows(CompletionException::class.java) {
- throw e
- }
- assertEquals(
- "Boom",
- e.message,
- )
- }
- }
-
- @Test
- fun test_fail_invoke_method_when_invoke_method_returns_a_bad_proto_using_toResponse() = runTest {
- val payload: UPayload = buildUPayload()
- try {
- thatReturnsTheWrongProto.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResponse()
- .first()
- fail("should not reach here")
- } catch (e: Exception) {
- assertThrows(RuntimeException::class.java) {
- throw e
- }
- assertEquals(
- "Unknown payload type [type.googleapis.com/google.protobuf.Int32Value]. Expected [io.cloudevents.v1.proto.CloudEvent]",
- e.message,
- )
- }
- }
-
- @Test
- @DisplayName("Invoke method that expects a UStatus payload and returns successfully with OK UStatus in the payload")
- fun test_success_invoke_method_happy_flow_that_returns_status_using_toResponse() = runTest {
- val payload: UPayload = buildUPayload()
- withStatusCodeHappyPath.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResponse().first()
- .run {
- assertEquals(UCode.OK, code)
- assertEquals("all good", message)
- }
- }
-
- @Test
- @DisplayName("test invalid payload that is not of type any")
- fun test_invalid_payload_that_is_not_type_any() = runTest {
- val payload: UPayload = buildUPayload()
- try {
- thatBarfsCrapyPayload.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResponse()
- .first()
- fail("should not reach here")
- } catch (e: Exception) {
- assertThrows(RuntimeException::class.java) {
- throw e
- }
- assertEquals(
- "Protocol message contained an invalid tag (zero). [org.eclipse.uprotocol.v1.UStatus]",
- e.message,
- )
- }
- }
-
- @Test
- fun test_no_payload_in_umessage() = runTest {
- val payload: UPayload = buildUPayload()
- try {
- thatReturnsUMessageWithoutPayload.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResponse()
- .first()
- fail("should not reach here")
- } catch (e: Exception) {
- assertThrows(RuntimeException::class.java) {
- throw e
- }
- assertEquals(
- "Server returned a null payload. Expected [io.cloudevents.v1.proto.CloudEvent]",
- e.message,
- )
- }
- }
-
-
- @Test
- fun test_toResult_nonUStatus_happy_path() = runTest {
- val payload = buildUPayload()
- returnsNumber3.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResult().first().run {
- assertTrue(isSuccess)
- assertEquals(Int32Value.of(3), getOrNull())
- }
- }
-
- @Test
- fun test_toResult_uStatus_happy_path() = runTest {
- val payload = buildUPayload()
- withStatusCodeHappyPath.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResult().first()
- .run {
- assertTrue(isSuccess)
- assertEquals(UCode.OK, getOrNull()?.code)
- assertEquals("all good", getOrNull()?.message)
-
- }
- }
-
- @Test
- fun test_toResult_uStatus_not_ok() = runTest {
- val payload = buildUPayload()
- withStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUCallOptions()).toResult()
- .first().run {
- assertTrue(isFailure)
- assertTrue(exceptionOrNull() is IllegalStateException)
- assertEquals("boom, UStatus: INVALID_ARGUMENT", exceptionOrNull()?.message)
- }
- }
-
- @Test
- fun test_toResult_no_payload_in_umessage() = runTest {
- val payload: UPayload = buildUPayload()
- thatReturnsUMessageWithoutPayload.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResult()
- .first().run {
- assertTrue(isFailure)
- assertTrue(exceptionOrNull() is RuntimeException)
- assertEquals(
- "Server returned a null payload. Expected [io.cloudevents.v1.proto.CloudEvent]",
- exceptionOrNull()?.message
- )
- }
- }
-
-
- @Test
- fun test_fail_invoke_method_when_invoke_method_threw_an_exception_using_toResult() = runTest {
- val payload: UPayload = buildUPayload()
- thatFlowWithAnException.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResult().first().run {
- assertTrue(isFailure)
- assertTrue(exceptionOrNull() is CompletionException)
- assertEquals(
- "Boom",
- exceptionOrNull()?.message
- )
- }
- }
-
- @Test
- fun test_fail_invoke_method_when_invoke_method_returns_a_status_using_toResult() = runTest {
- val payload: UPayload = buildUPayload()
- withStatusCodeInsteadOfHappyPath.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResult().first().run {
- assertTrue(isFailure)
- assertTrue(exceptionOrNull() is RuntimeException)
- assertEquals(
- "Unknown payload type [type.googleapis.com/uprotocol.v1.UStatus]. Expected [io.cloudevents.v1.proto.CloudEvent]",
- exceptionOrNull()?.message
- )
- }
- }
-
- @Test
- @DisplayName("test toResult with invalid payload that is not of type any")
- fun test_invalid_payload_that_is_not_type_any_toResult() = runTest {
- val payload: UPayload = buildUPayload()
- thatBarfsCrapyPayload.invokeMethod(buildTopic(), payload, buildUCallOptions())
- .toResult().first().run {
- assertTrue(isFailure)
- assertTrue(exceptionOrNull() is RuntimeException)
- assertEquals(
- "Protocol message contained an invalid tag (zero). [org.eclipse.uprotocol.v1.UStatus]",
- exceptionOrNull()?.message
- )
- }
-
- }
-
- private fun buildCloudEvent(): CloudEvent {
- return CloudEvent.newBuilder().setSpecVersion("1.0").setId("HARTLEY IS THE BEST")
- .setSource("https://example.com").build()
- }
-
- private fun buildUPayload(): UPayload {
- val any: Any = Any.pack(buildCloudEvent())
- return uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF
- value = any.toByteString()
- }
- }
-
- private val testUMessage = uMessage {
- payload = buildUPayload()
- }
-
- private fun buildTopic(): UUri {
- return LongUriSerializer.INSTANCE.deserialize("//vcu.vin/hartley/1/rpc.Raise")
- }
-
- private fun buildUCallOptions(): CallOptions {
- return callOptions { }
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/v1/UAttributesKtExtTest.kt b/src/test/kotlin/org/eclipse/uprotocol/transport/UAttributesKtExtTest.kt
similarity index 74%
rename from src/test/kotlin/org/eclipse/uprotocol/v1/UAttributesKtExtTest.kt
rename to src/test/kotlin/org/eclipse/uprotocol/transport/UAttributesKtExtTest.kt
index f3c52a1..20533cb 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/v1/UAttributesKtExtTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/transport/UAttributesKtExtTest.kt
@@ -1,25 +1,18 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
-package org.eclipse.uprotocol.v1
+package org.eclipse.uprotocol.transport
+import org.eclipse.uprotocol.v1.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
@@ -113,12 +106,6 @@ class UAttributesKtExtTest {
}
private val testSink = uUri {
- authority = uAuthority { name = "vcu.someVin.veh.ultifi.gm.com" }
- entity = uEntity {
- name = "petapp.ultifi.gm.com"
- versionMajor = 1
- }
- resource = uResource { forRpcResponse() }
}
@@ -130,10 +117,5 @@ class UAttributesKtExtTest {
}
private val testSource: UUri = uUri {
- entity = uEntity {
- name = "hartley_app"
- versionMajor = 1
- }
- resource = uResource { forRpcResponse() }
}
}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/transport/UMessageKtExtKtTest.kt b/src/test/kotlin/org/eclipse/uprotocol/transport/UMessageKtExtKtTest.kt
new file mode 100644
index 0000000..5278749
--- /dev/null
+++ b/src/test/kotlin/org/eclipse/uprotocol/transport/UMessageKtExtKtTest.kt
@@ -0,0 +1,286 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.transport
+
+import com.google.protobuf.Any
+import org.eclipse.uprotocol.v1.*
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertNotNull
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+
+class UMessageKtExtKtTest {
+ private val testSource = uUri {
+ ueId = 2
+ ueVersionMajor = 1
+ resourceId = 0
+ }
+ private val testSink = uUri {
+ authorityName = "vcu.someVin.veh.ultifi.gm.com"
+ ueId = 1
+ ueVersionMajor = 1
+ resourceId = 0
+ }
+
+ private val testUUID = uUID {
+ val uuidJava = java.util.UUID.randomUUID()
+ msb = uuidJava.mostSignificantBits
+ lsb = uuidJava.leastSignificantBits
+ }
+
+ @Test
+ fun testPublish() {
+ val publish: UMessage = uMessage {
+ forPublication(testSource)
+ }
+
+ assertNotNull(publish)
+ assertEquals(UMessageType.UMESSAGE_TYPE_PUBLISH, publish.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS1, publish.attributes.priority)
+ }
+
+ @Test
+ fun testNotification() {
+ val notification: UMessage = uMessage {
+ forNotification(testSource, testSink)
+ }
+ assertNotNull(notification)
+ assertEquals(UMessageType.UMESSAGE_TYPE_NOTIFICATION, notification.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS1, notification.attributes.priority)
+ assertEquals(testSink, notification.attributes.sink)
+ }
+
+ @Test
+ fun testRequest() {
+ val ttl = 1000
+ val request: UMessage = uMessage {
+ forRequest(testSource, testSink, ttl)
+ }
+ assertNotNull(request)
+ assertEquals(UMessageType.UMESSAGE_TYPE_REQUEST, request.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS4, request.attributes.priority)
+ assertEquals(testSink, request.attributes.sink)
+ assertEquals(ttl, request.attributes.ttl)
+ }
+
+ @Test
+ fun testResponse() {
+ val reqId = testUUID
+ val response: UMessage = uMessage {
+ forResponse(testSource, testSink, reqId)
+ }
+ assertNotNull(response)
+ assertEquals(UMessageType.UMESSAGE_TYPE_RESPONSE, response.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS4, response.attributes.priority)
+ assertEquals(testSink, response.attributes.sink)
+ assertEquals(reqId, response.attributes.reqid)
+ }
+
+ @Test
+ @DisplayName("Test response with existing request")
+ fun testResponseWithExistingRequest() {
+ val request: UMessage = uMessage {
+ forRequest(testSource, testSink, 1000)
+
+ }
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
+ }
+ assertNotNull(response)
+ assertEquals(UMessageType.UMESSAGE_TYPE_RESPONSE, response.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS4, request.attributes.priority)
+ assertEquals(UPriority.UPRIORITY_CS4, response.attributes.priority)
+ assertEquals(request.attributes.source, response.attributes.sink)
+ assertEquals(request.attributes.sink, response.attributes.source)
+ assertEquals(request.attributes.id, response.attributes.reqid)
+ }
+
+ @Test
+ @DisplayName("Test building UMessage with google.protobuf.Message payload")
+ fun testBuildWithPayload() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setPayload(testSink)
+ }
+ assertNotNull(message)
+ assertNotNull(message.payload)
+ assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF, message.attributes.payloadFormat)
+ assertEquals(testSink.toByteString(), message.payload)
+ }
+
+ @Test
+ @DisplayName("Test building UMessage with UPayload payload")
+ fun testBuildWithUPayload() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setPayload(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF, testSink.toByteString())
+ }
+ assertNotNull(message)
+ assertNotNull(message.payload)
+ assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF, message.attributes.payloadFormat)
+ assertEquals(testSink.toByteString(), message.payload)
+ }
+
+ @Test
+ @DisplayName("Test building UMessage with google.protobuf.Any payload")
+ fun testBuildWithAnyPayload() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setPayload(Any.getDefaultInstance())
+ }
+ assertNotNull(message)
+ assertNotNull(message.payload)
+ assertEquals(
+ UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY,
+ message.attributes.payloadFormat
+ )
+ assertEquals(Any.getDefaultInstance().toByteString(), message.payload)
+ }
+
+
+ @Test
+ @DisplayName("Test building response message with the wrong priority value of UPRIORITY_CS3")
+ fun testBuildResponseWithWrongPriority() {
+ val reqId = testUUID
+ val response: UMessage = uMessage {
+ forResponse(testSource, testSink, reqId)
+ setPriority(UPriority.UPRIORITY_CS3)
+ }
+ assertNotNull(response)
+ assertEquals(UMessageType.UMESSAGE_TYPE_RESPONSE, response.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS4, response.attributes.priority)
+ assertEquals(testSink, response.attributes.sink)
+ assertEquals(reqId, response.attributes.reqid)
+ }
+
+ @Test
+ @DisplayName("Test building request message with the wrong priority value of UPRIORITY_CS3")
+ fun testBuildRequestWithWrongPriority() {
+ val ttl = 1000
+ val request: UMessage = uMessage {
+ forRequest(testSource, testSink, ttl)
+ setPriority(UPriority.UPRIORITY_CS3)
+ }
+
+ assertNotNull(request)
+ assertEquals(UMessageType.UMESSAGE_TYPE_REQUEST, request.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS4, request.attributes.priority)
+ assertEquals(testSink, request.attributes.sink)
+ assertEquals(ttl, request.attributes.ttl)
+ }
+
+ @Test
+ @DisplayName("Test building notification message with the wrong priority value of UPRIORITY_CS0")
+ fun testBuildNotificationWithWrongPriority() {
+ val notification: UMessage = uMessage {
+ forNotification(testSource, testSink)
+ setPriority(UPriority.UPRIORITY_CS0)
+ }
+ assertNotNull(notification)
+ assertEquals(UMessageType.UMESSAGE_TYPE_NOTIFICATION, notification.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS1, notification.attributes.priority)
+ assertEquals(testSink, notification.attributes.sink)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with the wrong priority value of UPRIORITY_CS0")
+ fun testBuildPublishWithWrongPriority() {
+ val publish: UMessage = uMessage {
+ forPublication(testSource)
+ setPriority(UPriority.UPRIORITY_CS0)
+ }
+ assertNotNull(publish)
+ assertEquals(UMessageType.UMESSAGE_TYPE_PUBLISH, publish.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS1, publish.attributes.priority)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with the priority value of UPRIORITY_CS4")
+ fun testBuildPublishWithPriority() {
+ val publish: UMessage = uMessage {
+ forPublication(testSource)
+ setPriority(UPriority.UPRIORITY_CS4)
+
+ }
+ assertNotNull(publish)
+ assertEquals(UMessageType.UMESSAGE_TYPE_PUBLISH, publish.attributes.type)
+ assertEquals(UPriority.UPRIORITY_CS4, publish.attributes.priority)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with a different Permission level")
+ fun testSetPermissionLevel() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setPermissionLevel(5)
+ }
+ assertNotNull(message)
+ assertEquals(5, message.attributes.permissionLevel)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with a different ttl")
+ fun testSetTtl() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setTtl(1000)
+ }
+ assertNotNull(message)
+ assertEquals(1000, message.attributes.ttl)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with a different commstatus")
+ fun testSetCommStatus() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setCommStatus(UCode.OK)
+ }
+ assertNotNull(message)
+ assertEquals(UCode.OK, message.attributes.commstatus)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with a different reqid")
+ fun testSetReqid() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setReqid(testUUID)
+ }
+ assertNotNull(message)
+ assertEquals(testUUID, message.attributes.reqid)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with a different token")
+ fun testSetToken() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setToken("test_token")
+ }
+ assertNotNull(message)
+ assertEquals("test_token", message.attributes.token)
+ }
+
+ @Test
+ @DisplayName("Test building publish message with a different traceparent")
+ fun testSetTraceparent() {
+ val message: UMessage = uMessage {
+ forPublication(testSource)
+ setTraceparent("test_traceparent")
+ }
+ assertNotNull(message)
+ assertEquals("test_traceparent", message.attributes.traceparent)
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/transport/UPayloadExtTest.kt b/src/test/kotlin/org/eclipse/uprotocol/transport/UPayloadExtTest.kt
deleted file mode 100644
index 69eaf0c..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/transport/UPayloadExtTest.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.eclipse.uprotocol.transport
-
-import org.junit.jupiter.api.Test
-
-import org.eclipse.uprotocol.v1.*
-import kotlin.test.assertEquals
-import kotlin.test.assertNull
-
-class UPayloadExtTest {
-
- @Test
- fun test_unpack_with_UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY(){
- val message = uStatus { }
- val payload = uPayload {
- packToAny(message)
- }
- val result = unpack(payload, UStatus::class.java)
- checkNotNull(result)
- assertEquals(message, result)
- }
-
- @Test
- fun test_unpack_with_UPAYLOAD_FORMAT_PROTOBUF(){
- val message = uStatus { }
- val payload = uPayload {
- pack(message)
- }
- val result = unpack(payload, UStatus::class.java)
- checkNotNull(result)
- assertEquals(message, result)
- }
-
- @Test
- fun test_unpack_with_UPAYLOAD_FORMAT_RAW(){
- val message = uStatus { }
- val payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_RAW
- value = message.toByteString()
- }
- val result = unpack(payload, UStatus::class.java)
- assertNull(result)
- }
-
- @Test
- fun test_unpack_but_InvalidProtocolBufferException(){
- val message = uStatus { }
- val payload = uPayload {
- packToAny(message)
- }
- val result = unpack(payload, UUri::class.java)
- assertNull(result)
- }
-
- @Test
- fun test_inline_unpack_with_UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY(){
- val message = uStatus { }
- val payload = uPayload {
- packToAny(message)
- }
- val result = payload.unpack()
- checkNotNull(result)
- assertEquals(message, result)
- }
-
- @Test
- fun test_inline_unpack_with_UPAYLOAD_FORMAT_PROTOBUF(){
- val message = uStatus { }
- val payload = uPayload {
- pack(message)
- }
- val result = payload.unpack()
- checkNotNull(result)
- assertEquals(message, result)
- }
-
- @Test
- fun test_inline_unpack_with_UPAYLOAD_FORMAT_RAW(){
- val message = uStatus { }
- val payload = uPayload {
- format = UPayloadFormat.UPAYLOAD_FORMAT_RAW
- value = message.toByteString()
- }
- val result = payload.unpack()
- assertNull(result)
- }
-
- @Test
- fun test_inline_unpack_but_InvalidProtocolBufferException(){
- val message = uStatus { }
- val payload = uPayload {
- packToAny(message)
- }
- val result = payload.unpack()
- assertNull(result)
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/transport/UTransportTest.kt b/src/test/kotlin/org/eclipse/uprotocol/transport/UTransportTest.kt
index 8606d65..e1aedcf 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/transport/UTransportTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/transport/UTransportTest.kt
@@ -1,22 +1,14 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.transport
@@ -31,19 +23,18 @@ import org.junit.jupiter.api.Test
* Test implementing and using uTransport API
*/
class UTransportTest {
- @Test
- @DisplayName("Test happy path send message parts")
- fun test_happy_send_message_parts() {
- val transport: UTransport = HappyUTransport()
- val status = transport.send(UMessage.getDefaultInstance())
- assertEquals(status.code, UCode.OK)
- }
-
@Test
@DisplayName("Test happy path send message")
fun test_happy_send_message() {
val transport: UTransport = HappyUTransport()
- val status = transport.send(UMessage.getDefaultInstance())
+ val uri = uUri {
+ ueId = 1
+ ueVersionMajor = 1
+ resourceId = 0x8000
+
+ }
+
+ val status = transport.send(uMessage { forPublication(uri) })
assertEquals(status.code, UCode.OK)
}
@@ -51,7 +42,7 @@ class UTransportTest {
@DisplayName("Test happy path register listener")
fun test_happy_register_listener() {
val transport: UTransport = HappyUTransport()
- val status = transport.registerListener(UUri.getDefaultInstance(), MyListener())
+ val status = transport.registerListener(UUri.getDefaultInstance(), listener = MyListener())
assertEquals(status.code, UCode.OK)
}
@@ -59,24 +50,15 @@ class UTransportTest {
@DisplayName("Test happy path unregister listener")
fun test_happy_register_unlistener() {
val transport: UTransport = HappyUTransport()
- val status = transport.unregisterListener(UUri.getDefaultInstance(), MyListener())
+ val status = transport.unregisterListener(UUri.getDefaultInstance(), listener = MyListener())
assertEquals(status.code, UCode.OK)
}
- @Test
- @DisplayName("Test unhappy path send message parts")
- fun test_unhappy_send_message_parts() {
- val transport: UTransport = SadUTransport()
- val status = transport.send(UMessage.getDefaultInstance())
-
- assertEquals(status.code, UCode.INTERNAL)
- }
-
@Test
@DisplayName("Test unhappy path send message")
fun test_unhappy_send_message() {
val transport: UTransport = SadUTransport()
- val status = transport.send(UMessage.getDefaultInstance())
+ val status = transport.send(uMessage { })
assertEquals(status.code, UCode.INTERNAL)
}
@@ -84,7 +66,7 @@ class UTransportTest {
@DisplayName("Test unhappy path register listener")
fun test_unhappy_register_listener() {
val transport: UTransport = SadUTransport()
- val status = transport.registerListener(UUri.getDefaultInstance(), MyListener())
+ val status = transport.registerListener(UUri.getDefaultInstance(), listener = MyListener())
assertEquals(status.code, UCode.INTERNAL)
}
@@ -92,10 +74,26 @@ class UTransportTest {
@DisplayName("Test unhappy path unregister listener")
fun test_unhappy_register_unlistener() {
val transport: UTransport = SadUTransport()
- val status = transport.unregisterListener(UUri.getDefaultInstance(), MyListener())
+ val status = transport.unregisterListener(UUri.getDefaultInstance(), listener = MyListener())
assertEquals(status.code, UCode.INTERNAL)
}
+ @Test
+ @DisplayName("Test happy path registerlistener with source filter only")
+ fun test_happy_register_listener_source_filter() {
+ val transport: UTransport = HappyUTransport()
+ val status = transport.registerListener(UUri.getDefaultInstance(), listener = MyListener())
+ assertEquals(status.code, UCode.OK)
+ }
+
+ @Test
+ @DisplayName("Test happy path unregisterlistener with source filter only")
+ fun test_happy_unregister_listener_source_filter() {
+ val transport: UTransport = HappyUTransport()
+ val status = transport.unregisterListener(UUri.getDefaultInstance(), listener = MyListener())
+ assertEquals(status.code, UCode.OK)
+ }
+
internal inner class MyListener : UListener {
override fun onReceive(message: UMessage) {}
}
@@ -107,18 +105,22 @@ class UTransportTest {
}
}
- override fun registerListener(topic: UUri, listener: UListener): UStatus {
+ override fun registerListener(sourceFilter: UUri, sinkFilter: UUri?, listener: UListener): UStatus {
listener.onReceive(uMessage { })
return uStatus {
code = UCode.OK
}
}
- override fun unregisterListener(topic: UUri, listener: UListener): UStatus {
+ override fun unregisterListener(sourceFilter: UUri, sinkFilter: UUri?, listener: UListener): UStatus {
return uStatus {
code = UCode.OK
}
}
+
+ override fun getSource(): UUri {
+ return uUri { }
+ }
}
private inner class SadUTransport : UTransport {
@@ -128,17 +130,23 @@ class UTransportTest {
}
}
- override fun registerListener(topic: UUri, listener: UListener): UStatus {
+ override fun registerListener(sourceFilter: UUri, sinkFilter: UUri?, listener: UListener): UStatus {
listener.onReceive(uMessage { })
return uStatus {
code = UCode.INTERNAL
}
}
- override fun unregisterListener(topic: UUri, listener: UListener): UStatus {
+ override fun unregisterListener(sourceFilter: UUri, sinkFilter: UUri?, listener: UListener): UStatus {
return uStatus {
code = UCode.INTERNAL
}
}
+
+ override fun getSource(): UUri {
+ return uUri { }
+ }
}
+
+
}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.kt b/src/test/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.kt
index 32db1ac..f3974ab 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.kt
@@ -1,29 +1,20 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
+
package org.eclipse.uprotocol.transport.validator
-import org.eclipse.uprotocol.transport.validate.*
-import org.eclipse.uprotocol.transport.validate.UAttributesValidator.Companion.getValidator
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
-import org.eclipse.uprotocol.uuid.factory.UUIDV8
+import org.eclipse.uprotocol.transport.*
+import org.eclipse.uprotocol.transport.validator.UAttributesValidator.Companion.getValidator
import org.eclipse.uprotocol.v1.*
import org.eclipse.uprotocol.validation.ValidationResult
import org.junit.jupiter.api.Assertions.*
@@ -32,830 +23,537 @@ import org.junit.jupiter.api.Test
internal class UAttributesValidatorTest {
- @Test
- @DisplayName("test fetching validator for valid types")
- fun test_fetching_validator_for_valid_types() {
- val publish: UAttributesValidator = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- }.getValidator()
-
- assertEquals("UAttributesValidator.Publish", publish.toString())
- val request: UAttributesValidator = uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 1000)
- }.getValidator()
-
- assertEquals("UAttributesValidator.Request", request.toString())
- val response: UAttributesValidator = uAttributes {
- forResponse(testSource, testSink, UPriority.UPRIORITY_CS4, UUIDV8())
- }.getValidator()
-
- assertEquals("UAttributesValidator.Response", response.toString())
-
- val notification: UAttributesValidator = uAttributes {
- forNotification(testSource, testSink, UPriority.UPRIORITY_CS4)
- }.getValidator()
-
- assertEquals("UAttributesValidator.Notification", notification.toString())
+ private val defaultUUri = uUri {
+ ueId=1
+ ueVersionMajor=1
+ resourceId=0
}
- @Test
- @DisplayName("test using notification validator for publish type message")
- fun test_using_notification_validator_for_publish_type_message() {
- val attributes: UAttributes = uAttributes { forPublication(testSource, UPriority.UPRIORITY_CS0) }
- val validator: UAttributesValidator = Notification
- val status = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_PUBLISH],Missing Sink", status.getMessage())
+ private val methodUUri = uUri {
+ ueId=1
+ ueVersionMajor=1
+ resourceId=1
}
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published")
- fun test_validate_uAttributes_for_publish_message_payload() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
+ private val topicUUri = uUri {
+ ueId=1
+ ueVersionMajor=1
+ resourceId=0x8000
}
-
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published with all values")
- fun test_validate_uAttributes_for_publish_message_payload_all_values() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = 1000
- sink = testSink
- permissionLevel = 2
- commstatus = UCode.INVALID_ARGUMENT
- reqid = UUIDV8()
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
+ @DisplayName("Test creating a UMessage of type publish then validating it using UAttributeValidator for the happy path")
+ fun testUAttributeValidatorHappyPath() {
+ val message = uMessage {
+ forPublication(topicUUri)
+ }
+ val validator = message.attributes.getValidator()
+ val status: ValidationResult = validator.validate(message.attributes)
assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid type")
- fun test_validate_uAttributes_for_publish_message_payload_invalid_type() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource, testSink,
- UPriority.UPRIORITY_CS0, UUIDV8()
- )
+ @DisplayName("Test validation a notification message using UAttributeValidator")
+ fun testUAttributeValidatorNotification() {
+ val message: UMessage = uMessage {
+ forNotification(topicUUri, defaultUUri)
}
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_RESPONSE]", status.getMessage())
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isSuccess())
+ assertEquals(validator.toString(), "UAttributesValidator.Notification")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid time to live")
- fun test_validate_uAttributes_for_publish_message_payload_invalid_ttl() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = -1
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid TTL [-1]", status.getMessage())
+ @DisplayName("Test validation a request message using UAttributeValidator")
+ fun testUAttributeValidatorRequest() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isSuccess())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid sink")
- fun test_validate_uAttributes_for_publish_message_payload_invalid_sink() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- sink = UUri.getDefaultInstance()
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Uri is empty.", status.getMessage())
- }
+ @DisplayName("Test validation a response message using UAttributeValidator")
+ fun testUAttributeValidatorResponse() {
+ val request: UMessage =uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val response: UMessage = uMessage {
+ forResponse(methodUUri, defaultUUri, request.attributes.id)
+ }
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid permission level")
- fun test_validate_uAttributes_for_publish_message_payload_invalid_permission_level() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- permissionLevel = -42
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid Permission Level", status.getMessage())
- }
-
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published with invalid request id")
- fun test_validate_uAttributes_for_publish_message_payload_invalid_request_id() {
- val uuidJava: java.util.UUID = java.util.UUID.randomUUID()
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- reqid = uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
- }
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid UUID", status.getMessage())
+ val validator: UAttributesValidator = response.attributes.getValidator()
+ val result = validator.validate(response.attributes)
+ assertTrue(result.isSuccess())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "")
}
- // ----
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request")
- fun test_validate_uAttributes_for_rpc_request_message_payload() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 1000)
- }
+ @DisplayName("Test validation a response message using UAttributeValidator when passed request UAttributes")
+ fun testUAttributeValidatorResponseWithRequestAttributes() {
+ val request: UMessage =uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
+ }
- val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
+ val validator: UAttributesValidator = response.attributes.getValidator()
+ val result = validator.validate(response.attributes)
+ assertTrue(result.isSuccess())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with all values")
- fun test_validate_uAttributes_for_rpc_request_message_payload_all_values() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 1000)
- permissionLevel = 2
- commstatus = UCode.INVALID_ARGUMENT
- reqid = UUIDV8()
-
- }
+ @DisplayName("Test validation failed when using the publish validator to test request messages")
+ fun testUAttributeValidatorRequestWithPublishValidator() {
+ val message: UMessage =uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
- val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
+ val validator: UAttributesValidator = Publish
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Wrong Attribute Type [UMESSAGE_TYPE_REQUEST],Sink should not be present")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid type")
- fun test_validate_uAttributes_for_rpc_request_message_payload_invalid_type() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource, testSink,
- UPriority.UPRIORITY_CS4, UUIDV8()
- )
- ttl = 1000
+ @DisplayName("Test validation failed when using the notification validator to test publish messages")
+ fun testUAttributeValidatorPublishWithNotificationValidator() {
+ val message: UMessage = uMessage {
+ forPublication(topicUUri)
}
- val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_RESPONSE]", status.getMessage())
- }
-
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid time to live")
- fun test_validate_uAttributes_for_rpc_request_message_payload_invalid_ttl() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, -1)
- }
- val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid TTL [-1]", status.getMessage())
- }
-
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid sink")
- fun test_validate_uAttributes_for_rpc_request_message_payload_invalid_sink() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, UUri.getDefaultInstance(), UPriority.UPRIORITY_CS4, 1000)
- }
- val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Uri is empty.", status.getMessage())
+ val validator: UAttributesValidator = Notification
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Notification")
+ assertEquals(result.getMessage(), "Wrong Attribute Type [UMESSAGE_TYPE_PUBLISH],Missing Sink")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid permission level")
- fun test_validate_uAttributes_for_rpc_request_message_payload_invalid_permission_level() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 1000)
- permissionLevel = -42
- }
+ @DisplayName("Test validation failed when using the request validator to test response messages")
+ fun testUAttributeValidatorResponseWithRequestValidator() {
+ val request: UMessage =uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
+ }
val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid Permission Level", status.getMessage())
+ val result = validator.validate(response.attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
+ assertEquals(
+ result.getMessage(),
+ "Wrong Attribute Type [UMESSAGE_TYPE_RESPONSE],Missing TTL,Invalid Sink Uri,Message should not have a reqid"
+ )
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC request with invalid request id")
- fun test_validate_uAttributes_for_rpc_request_message_payload_invalid_request_id() {
- val uuidJava: java.util.UUID = java.util.UUID.randomUUID()
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 1000)
- reqid = uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
- }
- }
+ @DisplayName("Test validation failed when using the response validator to test notification messages")
+ fun testUAttributeValidatorNotificationWithResponseValidator() {
+ val message: UMessage = uMessage {
+ forNotification(topicUUri, defaultUUri)
+ }
- val validator: UAttributesValidator = Request
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid UUID", status.getMessage())
+ val validator: UAttributesValidator = Response
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(
+ result.getMessage(),
+ "Wrong Attribute Type [UMESSAGE_TYPE_NOTIFICATION],Invalid UPriority [UPRIORITY_CS1],Missing correlationId"
+ )
}
- // ----
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response")
- fun test_validate_uAttributes_for_rpc_response_message_payload() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource, testSink,
- UPriority.UPRIORITY_CS4, UUIDV8()
- )
+ @DisplayName("Test validation of request message has an invalid sink attribute")
+ fun testUAttributeValidatorRequestMissingSink() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, defaultUUri, 1000)
}
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
+
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
+ assertEquals(result.getMessage(), "Invalid Sink Uri")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with all values")
- fun test_validate_uAttributes_for_rpc_response_message_payload_all_values() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource, testSink,
- UPriority.UPRIORITY_CS4, UUIDV8()
- )
- permissionLevel = 2
- commstatus = UCode.INVALID_ARGUMENT
-
+ @DisplayName("Test validation of request message that has a permission level that is less than 0")
+ fun testUAttributeValidatorRequestInvalidPermissionLevel() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ setPermissionLevel(-1)
}
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
- }
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid type")
- fun test_validate_uAttributes_for_rpc_response_message_payload_invalid_type() {
- val attributes: UAttributes =
- uAttributes {
- forNotification(testSource, testSink, UPriority.UPRIORITY_CS4)
- }
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_NOTIFICATION],Missing correlationId", status.getMessage())
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
+ assertEquals(result.getMessage(), "Invalid Permission Level")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid time to live")
- fun test_validate_uAttributes_for_rpc_response_message_payload_invalid_ttl() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource, testSink,
- UPriority.UPRIORITY_CS4, UUIDV8()
- )
- ttl = -1
+ @DisplayName("Test validation of request message that has a permission level that is greater than 0")
+ fun testUAttributeValidatorRequestValidPermissionLevel() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ setPermissionLevel(1)
}
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid TTL [-1]", status.getMessage())
- }
-
- @Test
- @DisplayName(
- "Validate a UAttributes for payload that is meant to be an RPC response with missing sink and " + "missing request id"
- )
- fun test_validate_uAttributes_for_rpc_response_message_payload_missing_sink_and_missing_requestId() {
- val attributes: UAttributes =
- uAttributes {
- forResponse(
- testSource,
- UUri.getDefaultInstance(),
- UPriority.UPRIORITY_CS4,
- UUID.getDefaultInstance()
- )
- }
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Missing Sink,Missing correlationId", status.getMessage())
+
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isSuccess())
+ assertFalse(validator.isExpired(message.attributes))
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid permission level")
- fun test_validate_uAttributes_for_rpc_response_message_payload_invalid_permission_level() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource, testSink,
- UPriority.UPRIORITY_CS4, UUIDV8()
- )
- permissionLevel = -42
+ @DisplayName("Test validation of request message that has TTL that is less than 0")
+ fun testUAttributeValidatorRequestInvalidTTL() {
+ val message: UMessage = uMessage {
+ forPublication(topicUUri)
+ setTtl(-1)
}
- val validator: UAttributesValidator = Response
- val status: ValidationResult = 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 missing request id")
- fun test_validate_uAttributes_for_rpc_response_message_payload_missing_request_id() {
- val attributes: UAttributes =
- uAttributes {
- forResponse(testSource, testSink, UPriority.UPRIORITY_CS4, UUID.getDefaultInstance())
- }
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Missing correlationId", status.getMessage())
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
+ assertTrue(result.isFailure())
+ assertFalse(validator.isExpired(message.attributes))
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Invalid TTL [-1]")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be an RPC response with invalid request id")
- fun test_validate_uAttributes_for_rpc_response_message_payload_invalid_request_id() {
- val uuidJava: java.util.UUID = java.util.UUID.randomUUID()
- val reqid: UUID = uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
+ @DisplayName("Test validation of request message where the message has expired")
+// @Throws(
+// InterruptedException::class
+// )
+ fun testUAttributeValidatorRequestExpired() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1)
}
- val attributes: UAttributes =
- uAttributes { forResponse(testSource, testSink, UPriority.UPRIORITY_CS4, reqid) }
- val validator: UAttributesValidator = Response
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid correlationId [$reqid]", status.getMessage())
+ Thread.sleep(100)
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ assertTrue(validator.isExpired(message.attributes))
}
- // ----
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published not expired")
- fun test_validate_uAttributes_for_publish_message_payload_not_expired() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
+ @DisplayName("Test validator isExpired() for an ID that is mall formed and doesn't have the time")
+ fun testUAttributeValidatorRequestExpiredMalformedId() {
+ val attributes = uAttributes {
+ id = uUID { }
+ type = UMessageType.UMESSAGE_TYPE_REQUEST
}
- val validator: UAttributesValidator = Publish
+ val validator: UAttributesValidator = attributes.getValidator()
assertFalse(validator.isExpired(attributes))
}
@Test
- @DisplayName("Validate a UAttributes isExpired() for an invalid UUID of UAttributes")
- fun test_validate_uAttributes_isExpired_for_invalid_UUID() {
- val attributes = UAttributes.getDefaultInstance()
- val validator = Publish
- assertFalse(validator.isExpired(attributes))
- }
+ @DisplayName("Test validation fails when a publish messages has a reqid")
+ fun testUAttributeValidatorPublishWithReqId() {
+ val publish: UMessage = uMessage {
+ forPublication(topicUUri)
+ }
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published not expired with ttl zero")
- fun test_validate_uAttributes_for_publish_message_payload_not_expired_with_ttl_zero() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = 0
- }
- val validator: UAttributesValidator = Publish
- assertFalse(validator.isExpired(attributes))
- }
+ val attributes = publish.attributes.copy {
+ reqid = uUID { }
+ }
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published not expired with ttl")
- fun test_validate_uAttributes_for_publish_message_payload_not_expired_with_ttl() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = 10000
- }
- val validator: UAttributesValidator = Publish
- assertFalse(validator.isExpired(attributes))
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Message should not have a reqid")
}
@Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published not expired with ttl")
- fun test_validate_uAttributes_for_publish_message_payload_with_negative_ttl() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = -1
- }
-
- val validator: UAttributesValidator = Publish
- assertFalse(validator.isExpired(attributes))
- }
+ @DisplayName("Test notification validation where the sink is missing")
+ fun testUAttributeValidatorNotificationMissingSink() {
+ val message: UMessage =uMessage {
+ forNotification(topicUUri, defaultUUri)
+ }
+ val attributes = message.attributes.copy { clearSink() }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- @Test
- @DisplayName("Validate a UAttributes for payload that is meant to be published expired with ttl")
- @Throws(
- InterruptedException::class
- )
- fun test_validate_uAttributes_for_publish_message_payload_expired_with_ttl() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = 1
- }
- Thread.sleep(800)
- val validator: UAttributesValidator = Publish
- assertTrue(validator.isExpired(attributes))
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Notification")
+ assertEquals(result.getMessage(), "Missing Sink")
}
- // ----
@Test
- @DisplayName("test validating publish invalid ttl attribute")
- fun test_validating_publish_invalid_ttl_attribute() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = -1
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validateTtl(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid TTL [-1]", status.getMessage())
- }
+ @DisplayName("Test notification validation where the sink the default instance")
+ fun testUAttributeValidatorNotificationDefaultSink() {
+ val message: UMessage =uMessage {
+ forNotification(topicUUri, defaultUUri)
+ }
+ val attributes = message.attributes.copy {
+ sink = UUri.getDefaultInstance()
+ }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- @Test
- @DisplayName("test validating publish valid ttl attribute")
- fun test_validating_valid_ttl_attribute() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = 100
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validateTtl(attributes)
- assertEquals(ValidationResult.success(), status)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Notification")
+ assertEquals(result.getMessage(), "Missing Sink")
}
@Test
- @DisplayName("test validating invalid sink attribute")
- fun test_validating_invalid_sink_attribute() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("//")
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- sink = uri
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validateSink(attributes)
- assertTrue(status.isFailure())
- assertEquals("Uri is empty.", status.getMessage())
- }
+ @DisplayName("Test notification validation where the sink is NOT the defaultResourceId")
+ fun testUAttributeValidatorNotificationDefaultResourceId() {
+ val message: UMessage = uMessage {
+ forNotification(topicUUri, topicUUri)
+ }
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
- @Test
- @DisplayName("test validating valid sink attribute")
- fun test_validating_valid_sink_attribute() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/haartley/1")
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- sink = uri
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validateSink(attributes)
- assertEquals(ValidationResult.success(), status)
- }
-
- @Test
- @DisplayName("test validating invalid ReqId attribute")
- fun test_validating_invalid_ReqId_attribute() {
- val uuidJava: java.util.UUID = java.util.UUID.randomUUID()
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- reqid = uUID {
- msb = uuidJava.mostSignificantBits
- lsb = uuidJava.leastSignificantBits
- }
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validateReqId(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid UUID", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Notification")
+ assertEquals(result.getMessage(), "Invalid Sink Uri")
}
@Test
- @DisplayName("test validating valid ReqId attribute")
- fun test_validating_valid_ReqId_attribute() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- reqid = UUIDV8()
+ @DisplayName("Test validatePriority when priority is less than CS1")
+ fun testUAttributeValidatorValidatePriorityLessThanCS1() {
+ val message: UMessage = uMessage {
+ forPublication(topicUUri)
}
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validateReqId(attributes)
- assertEquals(ValidationResult.success(), status)
- }
+ val attributes = message.attributes.copy { priority = UPriority.UPRIORITY_CS0 }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- @Test
- @DisplayName("test validating invalid PermissionLevel attribute")
- fun test_validating_invalid_PermissionLevel_attribute() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- permissionLevel = -1
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validatePermissionLevel(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid Permission Level", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Invalid UPriority [UPRIORITY_CS0]")
}
@Test
- @DisplayName("test validating valid PermissionLevel attribute")
- fun test_validating_valid_PermissionLevel_attribute() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- permissionLevel = 3
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validatePermissionLevel(attributes)
- assertEquals(ValidationResult.success(), status)
- }
+ @DisplayName("Test validateId when id is missing")
+ fun testUAttributeValidatorValidateIdMissing() {
+ val message: UMessage = uMessage {
+ forPublication(topicUUri)
+ }
+ val attributes = message.attributes.copy { clearId() }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- @Test
- @DisplayName("test validating valid PermissionLevel attribute")
- fun test_validating_valid_PermissionLevel_attribute_invalid() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- permissionLevel = 0
- }
- val validator: UAttributesValidator = Publish
- val status: ValidationResult = validator.validatePermissionLevel(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid Permission Level", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Missing id")
}
@Test
- @DisplayName("test validating request message types")
- fun test_validating_request_message_types() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS6, 100)
- }
-
+ @DisplayName("Test validateId when id is the default instance")
+ fun testUAttributeValidatorValidateIdDefault() {
+ val message: UMessage = uMessage {
+ forPublication(topicUUri)
+ }
+ val attributes = message.attributes.copy { id = UUID.getDefaultInstance() }
val validator: UAttributesValidator = attributes.getValidator()
- assertEquals("UAttributesValidator.Request", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
- }
+ val result = validator.validate(attributes)
- @Test
- @DisplayName("test validating request validator using wrong messagetype")
- fun test_validating_request_validator_with_wrong_messagetype() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS6)
- }
- val validator: UAttributesValidator = Request
- assertEquals("UAttributesValidator.Request", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_PUBLISH],Missing TTL,Missing Sink", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Attributes must contain valid uProtocol UUID in id property")
}
@Test
- @DisplayName("test validating request validator using bad ttl")
- fun test_validating_request_validator_with_wrong_bad_ttl() {
- val attributes: UAttributes = uAttributes {
- forRequest(
- testSource, LongUriSerializer.INSTANCE.deserialize("/hartley/1/rpc.response"),
- UPriority.UPRIORITY_CS6, -1
- )
+ @DisplayName("Test publish validateSink when sink is not empty")
+ fun testUAttributeValidatorValidateSinkNotEmpty() {
+ val message: UMessage = uMessage {
+ forPublication(topicUUri)
}
+ val attributes: UAttributes = message.attributes.copy { sink = defaultUUri }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- val validator: UAttributesValidator = Request
- assertEquals("UAttributesValidator.Request", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid TTL [-1]", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Publish")
+ assertEquals(result.getMessage(), "Sink should not be present")
}
@Test
- @DisplayName("test validating response validator using bad ttl")
- fun test_validating_response_validator_with_wrong_bad_ttl() {
- val attributes: UAttributes = uAttributes {
- forResponse(
- testSource,
- LongUriSerializer.INSTANCE.deserialize("/hartley/1/rpc.response"),
- UPriority.UPRIORITY_CS6,
- UUIDV8()
- )
- ttl = -1
+ @DisplayName("Test validateSink of a request message that is missing a sink")
+ fun testUAttributeValidatorValidateSinkMissing() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
}
- val validator: UAttributesValidator = Response
- assertEquals("UAttributesValidator.Response", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Invalid TTL [-1]", status.getMessage())
- }
- @Test
- @DisplayName("test validating publish validator with wrong messagetype")
- fun test_validating_publish_validator_with_wrong_messagetype() {
- val attributes: UAttributes =
- uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS6, 1000)
- }
+ val attributes = message.attributes.copy { clearSink() }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- val validator: UAttributesValidator = Publish
- assertEquals("UAttributesValidator.Publish", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_REQUEST]", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
+ assertEquals(result.getMessage(), "Missing Sink")
}
@Test
- @DisplayName("test validating response validator with wrong messagetype")
- fun test_validating_response_validator_with_wrong_messagetype() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS6)
+ @DisplayName("Test validateTtl of a request message where ttl is less than 0")
+ fun testUAttributeValidatorValidateTtlLessThanZero() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, -1)
}
- val validator: UAttributesValidator = Response
- assertEquals("UAttributesValidator.Response", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals(
- "Wrong Attribute Type [UMESSAGE_TYPE_PUBLISH],Missing Sink,Missing correlationId", status.getMessage()
- )
- }
+ val validator: UAttributesValidator = message.attributes.getValidator()
+ val result = validator.validate(message.attributes)
- @Test
- @DisplayName("test validating request containing token")
- fun test_validating_request_containing_token() {
- val attributes: UAttributes =
- uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- token = "null"
- }
- val validator: UAttributesValidator = attributes.getValidator()
- assertEquals("UAttributesValidator.Publish", validator.toString())
- val status: ValidationResult = validator.validate(attributes)
- assertEquals(ValidationResult.success(), status)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
+ assertEquals(result.getMessage(), "Invalid TTL [-1]")
}
@Test
- @DisplayName("test_valid_request_methoduri_in_sink")
- fun test_valid_request_methoduri_in_sink() {
- val testSink = LongUriSerializer.INSTANCE.deserialize("/test.service/1/rpc.method")
- val attributes = uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 3000)
+ @DisplayName("Test validatePriority of a request message where priority is less than CS4")
+ fun testUAttributeValidatorValidatePriorityLessThanCS4() {
+ val message: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val attributes = message.attributes.copy {
+ priority = UPriority.UPRIORITY_CS3
}
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- val validator = attributes.getValidator()
- assertEquals("UAttributesValidator.Request", validator.toString())
- val status = validator.validate(attributes)
- assertEquals(ValidationResult.success(), status)
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Request")
+ assertEquals(result.getMessage(), "Invalid UPriority [UPRIORITY_CS3]")
}
@Test
- @DisplayName("test_invalid_request_methoduri_in_sink")
- fun test_invalid_request_methoduri_in_sink() {
- val testSink = LongUriSerializer.INSTANCE.deserialize("/test.client/1/test.response")
- val attributes = uAttributes {
- forRequest(testSource, testSink, UPriority.UPRIORITY_CS4, 3000)
+ @DisplayName("Test validateSink for a response message where the sink is missing")
+ fun testUAttributeValidatorValidateSinkResponseMissing() {
+ val request: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
}
+ val attributes = response.attributes.copy {
+ clearSink()
+ }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- val validator = attributes.getValidator()
- assertEquals("UAttributesValidator.Request", validator.toString())
- val status = validator.validate(attributes)
- assertEquals(
- "Invalid RPC method uri. Uri should be the method to be called, or method from response.",
- status.getMessage()
- )
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "Missing Sink")
}
@Test
- @DisplayName("test_valid_response_uri_in_sink")
- fun test_valid_response_uri_in_sink() {
- val testSink = LongUriSerializer.INSTANCE.deserialize("/test.client/1/rpc.response")
- val attributes = uAttributes {
- forResponse(
- testSource,
- testSink,
- UPriority.UPRIORITY_CS4,
- UUIDV8()
- )
+ @DisplayName("Test validateSink for a response message where the sink is the default instance")
+ fun testUAttributeValidatorValidateSinkResponseDefault() {
+ val request: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
}
- val validator = attributes.getValidator()
- assertEquals("UAttributesValidator.Response", validator.toString())
- val status = validator.validate(attributes)
- assertEquals(ValidationResult.success(), status)
- }
-
- @Test
- @DisplayName("test_invalid_response_uri_in_sink")
- fun test_invalid_response_uri_in_sink() {
- val testSink = LongUriSerializer.INSTANCE.deserialize("/test.client/1/rpc.method")
- val attributes = uAttributes {
- forResponse(
- testSource,
- testSink,
- UPriority.UPRIORITY_CS4,
- UUIDV8()
- )
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
}
- val validator = attributes.getValidator()
- assertEquals("UAttributesValidator.Response", validator.toString())
- val status = validator.validate(attributes)
- assertEquals("Invalid RPC response type.", status.getMessage())
- }
-
- @Test
- @DisplayName("test notification validation with missing sink")
- fun test_notification_validation_with_missing_sink() {
- val attributes: UAttributes = uAttributes {
- forNotification(testSource, UUri.getDefaultInstance(), UPriority.UPRIORITY_CS0)
+ val attributes = response.attributes.copy {
+ sink = UUri.getDefaultInstance()
}
- val validator: UAttributesValidator = Notification
- val status = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Missing Sink", status.getMessage())
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
+
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "Missing Sink")
}
@Test
- @DisplayName("test notification validation using publish validator")
- fun test_notification_validation_using_publish_validator() {
- val attributes: UAttributes = uAttributes {
- forNotification(testSource, testSink, UPriority.UPRIORITY_CS0)
+ @DisplayName("Test validateSink for a response message where the sink is NOT the defaultResourceId")
+ fun testUAttributeValidatorValidateSinkResponseDefaultResourceId() {
+ val request: UMessage = uMessage {
+ forRequest(methodUUri, defaultUUri, 1000)
}
- val validator: UAttributesValidator = Publish
- val status = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Wrong Attribute Type [UMESSAGE_TYPE_NOTIFICATION]", status.getMessage())
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
+ }
+ val validator: UAttributesValidator = response.attributes.getValidator()
+ val result = validator.validate(response.attributes)
+
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "Invalid Sink Uri")
}
@Test
- @DisplayName("test notification validation when sink is missing")
- fun test_notification_validation_when_sink_is_missing() {
- val attributes: UAttributes = uAttributes {
- id = UUIDV8()
- source = testSource
- type = UMessageType.UMESSAGE_TYPE_NOTIFICATION
- priority = UPriority.UPRIORITY_CS0
+ @DisplayName("Test validateReqId for a response message when the reqid is missing")
+ fun testUAttributeValidatorValidateReqIdMissing() {
+ val request: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
+ }
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
+ }
+ val attributes = response.attributes.copy {
+ clearReqid()
}
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
- val validator: UAttributesValidator = Notification
- val status = validator.validate(attributes)
- assertTrue(status.isFailure())
- assertEquals("Missing Sink", status.getMessage())
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "Missing correlationId")
}
@Test
- @DisplayName("test notification validation with a valid notification UAttributes")
- fun test_notification_validation_with_a_valid_notification_UAttributes() {
- val attributes: UAttributes = uAttributes {
- forNotification(testSource, testSink, UPriority.UPRIORITY_CS0)
+ @DisplayName("Test validateReqId for a response message when the reqid is the default instance")
+ fun testUAttributeValidatorValidateReqIdDefault() {
+ val request: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
}
- val validator: UAttributesValidator = Notification
- val status = validator.validate(attributes)
- assertTrue(status.isSuccess())
- assertEquals("", status.getMessage())
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
+ }
+ val attributes = response.attributes.copy { reqid = UUID.getDefaultInstance() }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
+
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "Missing correlationId")
}
- private val testSink = uUri {
- authority = uAuthority { name = "vcu.someVin.veh.ultifi.gm.com" }
- entity = uEntity {
- name = "petapp.ultifi.gm.com"
- versionMajor = 1
+ @Test
+ @DisplayName("Test validateReqId for a response message when the reqid not a valid uprotocol UUID")
+ fun testUAttributeValidatorValidateReqIdInvalid() {
+ val request: UMessage = uMessage {
+ forRequest(defaultUUri, methodUUri, 1000)
}
- resource = uResource {
- forRpcResponse()
+ val response: UMessage = uMessage {
+ forResponse(request.attributes)
}
+ val attributes = response.attributes.copy { reqid = uUID {
+ lsb = -0x41524111
+ msb = -0x21524111
+ } }
+ val validator: UAttributesValidator = attributes.getValidator()
+ val result = validator.validate(attributes)
+
+ assertTrue(result.isFailure())
+ assertEquals(validator.toString(), "UAttributesValidator.Response")
+ assertEquals(result.getMessage(), "Invalid correlation UUID")
}
- private val testSource: UUri = uUri {
- entity = uEntity {
- name = "hartley_app"
- versionMajor = 1
- }
- resource = uResource {
- forRpcResponse()
+ @Test
+ @DisplayName("Test getValidator for other type of messages")
+ fun testUAttributeValidatorGetValidatorForOtherTypes() {
+ val attributes1 = uAttributes {
+ type = UMessageType.UMESSAGE_TYPE_UNSPECIFIED
}
+ val validator1: UAttributesValidator = attributes1.getValidator()
+
+ assertTrue(validator1 is Publish)
}
}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/UUriExamples.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/UUriExamples.kt
new file mode 100644
index 0000000..86afd40
--- /dev/null
+++ b/src/test/kotlin/org/eclipse/uprotocol/uri/UUriExamples.kt
@@ -0,0 +1,62 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.uri
+
+import org.eclipse.uprotocol.core.usubscription.v3.USubscriptionProto
+import org.eclipse.uprotocol.uri.factory.UUriFactory
+import org.eclipse.uprotocol.uri.serializer.deserializeAsUUri
+import org.eclipse.uprotocol.uri.serializer.serialize
+import org.eclipse.uprotocol.uri.validator.*
+import org.eclipse.uprotocol.v1.UUri
+import org.eclipse.uprotocol.v1.uUri
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Test
+
+class UUriExamples {
+ @Test
+ fun example_UriFactory_FromProto() {
+ // Fetch the notification topic Uri from the USubscriptionProto generated code
+ val uri: UUri = UUriFactory.fromProto(USubscriptionProto.getDescriptor().services[0], 0)
+
+ assertEquals(uri.ueId, 0)
+ assertEquals(uri.ueVersionMajor, 3)
+ assertEquals(uri.resourceId, 0)
+ }
+
+ @Test
+ fun example_Serializer_Deserializer() {
+ val uri = uUri {
+ ueId = 1
+ ueVersionMajor = 2
+ resourceId = 3
+ }
+ val strUri: String = uri.serialize()
+ assertEquals("/1/2/3", strUri)
+ assertEquals(uri, strUri.deserializeAsUUri())
+ }
+
+ @Test
+ fun example_UriValidator() {
+ val uri = uUri {
+ ueId = 1
+ ueVersionMajor = 2
+ resourceId = 3
+ }
+ assertFalse(uri.isEmpty())
+ assertFalse(uri.isDefaultResourceId())
+ assertTrue(uri.isRpcMethod())
+ assertFalse(uri.isRpcResponse())
+ assertFalse(uri.isTopic())
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/factory/UEntityFactoryTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/factory/UEntityFactoryTest.kt
deleted file mode 100644
index c4b24f7..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/factory/UEntityFactoryTest.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.eclipse.uprotocol.uri.factory
-
-import org.eclipse.uprotocol.core.udiscovery.v3.UDiscoveryProto
-import org.eclipse.uprotocol.core.usubscription.v3.USubscriptionProto
-import org.eclipse.uprotocol.core.utwin.v2.UTwinProto
-import org.eclipse.uprotocol.uri.factory.UEntityFactory.fromProto
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-
-
-class UEntityFactoryTest{
- @Test
- @DisplayName("Test build valid usubscription UEntity")
- fun test_build_valid_usubscription_uentity() {
- val descriptor = USubscriptionProto.getDescriptor().services[0]
- val entity = fromProto(descriptor)
-
- assertEquals(entity.name, "core.usubscription")
- assertEquals(entity.id, 0)
- assertEquals(entity.versionMajor, 3)
- assertEquals(entity.versionMinor, 0)
- }
-
- @Test
- @DisplayName("Test build valid uDiscovery UEntity")
- fun test_build_valid_udiscovery_uentity() {
- val descriptor = UDiscoveryProto.getDescriptor().services[0]
-
- val entity = fromProto(descriptor)
-
- assertEquals(entity.name, "core.udiscovery")
- assertEquals(entity.id, 1)
- assertEquals(entity.versionMajor, 3)
- assertEquals(entity.versionMinor, 0)
- }
-
- @Test
- @DisplayName("Test build valid uTwin UEntity")
- fun test_build_valid_utwin_uentity() {
- val descriptor = UTwinProto.getDescriptor().services[0]
-
- val entity = fromProto(descriptor)
-
- assertEquals(entity.name, "core.utwin")
- assertEquals(entity.id, 26)
- assertEquals(entity.versionMajor, 2)
- assertEquals(entity.versionMinor, 0)
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/factory/UUriFactoryTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/factory/UUriFactoryTest.kt
new file mode 100644
index 0000000..89d1216
--- /dev/null
+++ b/src/test/kotlin/org/eclipse/uprotocol/uri/factory/UUriFactoryTest.kt
@@ -0,0 +1,72 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.uri.factory
+
+import org.eclipse.uprotocol.core.usubscription.v3.USubscriptionProto
+import org.eclipse.uprotocol.v1.UUri
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+
+class UUriFactoryTest {
+ @Test
+ @DisplayName("Test fromProto")
+ fun testFromProto() {
+ val uri: UUri = UUriFactory.fromProto(
+ USubscriptionProto.getDescriptor().services[0], 0
+ )
+
+ assertEquals(uri.authorityName, "")
+ assertEquals(uri.ueId, 0)
+ assertEquals(uri.ueVersionMajor, 3)
+ assertEquals(uri.resourceId, 0)
+ }
+
+ @Test
+ @DisplayName("Test ANY")
+ fun testAny() {
+ val uri: UUri = UUriFactory.ANY
+
+ assertEquals(uri.authorityName, "*")
+ assertEquals(uri.ueId, 65535)
+ assertEquals(uri.ueVersionMajor, 255)
+ assertEquals(uri.resourceId, 65535)
+ }
+
+ @Test
+ @DisplayName("Test fromProto with authority name")
+ fun testFromProtoWithAuthorityName() {
+ val uri: UUri = UUriFactory.fromProto(
+ USubscriptionProto.getDescriptor().services[0], 0, "hartley"
+ )
+
+ assertEquals(uri.authorityName, "hartley")
+ assertEquals(uri.ueId, 0)
+ assertEquals(uri.ueVersionMajor, 3)
+ assertEquals(uri.resourceId, 0)
+ }
+
+ @Test
+ @DisplayName("Test fromProto with empty authority name string")
+ fun testFromProtoWithEmptyAuthorityName() {
+ val uri: UUri = UUriFactory.fromProto(
+ USubscriptionProto.getDescriptor().services[0], 0, ""
+ )
+
+ assertEquals(uri.authorityName, "")
+ assertEquals(uri.ueId, 0)
+ assertEquals(uri.ueVersionMajor, 3)
+ assertEquals(uri.resourceId, 0)
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/IpAddressTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/IpAddressTest.kt
deleted file mode 100644
index 0ce93d8..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/IpAddressTest.kt
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.eclipse.uprotocol.uri.serializer
-
-import org.eclipse.uprotocol.uri.serializer.IpAddress.isValid
-import org.eclipse.uprotocol.uri.serializer.IpAddress.toBytes
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.InetAddress
-
-class IpAddressTest {
- @Test
- @DisplayName("Test toBytes with empty ipAddress")
- fun testToBytesWithEmptyIpAddress() {
- val bytes = toBytes("")
- assertEquals(0, bytes.size)
- }
-
- @Test
- @DisplayName("Test toBytes with invalid ipAddress")
- fun testToBytesWithInvalidIpAddress() {
- val bytes = toBytes("invalid")
- assertEquals(0, bytes.size)
- }
-
- @Test
- @DisplayName("Test toBytes with valid IPv4 address")
- fun testToBytesWithValidIPv4Address() {
- val bytes = toBytes("192.168.1.100")
- assertEquals(4, bytes.size)
- assertEquals(192, java.lang.Byte.toUnsignedInt(bytes[0]))
- assertEquals(168, java.lang.Byte.toUnsignedInt(bytes[1]))
- assertEquals(1, java.lang.Byte.toUnsignedInt(bytes[2]))
- assertEquals(100, java.lang.Byte.toUnsignedInt(bytes[3]))
- }
-
- @Test
- @DisplayName("Test toBytes with valid IPv6 address")
- fun testToBytesWithValidIPv6Address() {
- val bytes = toBytes("2001:db8:85a3:0:0:8a2e:370:7334")
-
- assertEquals(InetAddress.getByAddress(bytes).hostAddress, "2001:db8:85a3:0:0:8a2e:370:7334")
- }
-
- @Test
- @DisplayName("Test isValid with empty ipAddress")
- fun testIsValidWithEmptyIpAddress() {
- assertFalse(isValid(""))
- }
-
- @Test
- @DisplayName("Test isValid with invalid ipAddress")
- fun testIsValidWithInvalidIpAddress() {
- assertFalse(isValid("invalid"))
- }
-
- @Test
- @DisplayName("Test isValid with valid IPv4 address")
- fun testIsValidWithValidIPv4Address() {
- assertTrue(isValid("192.168.1.100"))
- }
-
- @Test
- @DisplayName("Test isValid with valid IPv6 address")
- fun testIsValidWithValidIPv6Address() {
- assertTrue(isValid("2001:db8:85a3:0:0:8a2e:370:7334"))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv4 address")
- fun testIsValidWithInvalidIPv4Address() {
- val bytes = toBytes("192.168.1.2586")
- assertEquals(0, bytes.size)
- assertFalse(isValid("192.168.1.2586"))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv4 passing large number")
- fun testIsValidWithInvalidIPv4PassingLargeNumber() {
- val ipString = "2875687346587326457836485623874658723645782364875623847562378465.1.1.abc"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
-
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv4 passing negative value")
- fun testIsValidWithInvalidIPv4PassingNegative() {
- val ipString = "-1.1.1.abc"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv4 passing charaters")
- fun testIsValidWithInvalidIPv4PassingCharacters() {
- val ipString = "1.1.1.abc"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address")
- fun testIsValidWithInvalidIPv6Address() {
- val ipString = "ZX1:db8::"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address passing weird values")
- fun testIsValidWithInvalidIPv6AddressPassingWeirdValues() {
- val ipString = "-1:ZX1:db8::"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address that has way too many groups")
- fun testIsValidWithInvalidIPv6AddressThatHasWayTooManyGroups() {
- val ipString = "2001:db8:85a3:0:0:8a2e:370:7334:1234"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with valid IPv6 address that has 8 groups")
- fun testIsValidWithValidIPv6AddressThatHas8Groups() {
- val ipString = "2001:db8:85a3:0:0:8a2e:370:7334"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address with too many empty groups")
- fun testIsValidWithInvalidIPv6AddressWithTooManyEmptyGroups() {
- val ipString = "2001::85a3::8a2e::7334"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with valid IPv6 address with one empty group")
- fun testIsValidWithValidIPv6AddressWithOneEmptyGroup() {
- val ipString = "2001:db8:85a3::8a2e:370:7334"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address that ends with a colon")
- fun testIsValidWithInvalidIPv6AddressThatEndsWithAColon() {
- val ipString = "2001:db8:85a3::8a2e:370:7334:"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address that has doesn't have double colon and not enough groups")
- fun testIsValidWithInvalidIPv6AddressThatHasDoesntHaveDoubleColonAndNotEnoughGroups() {
- val ipString = "2001:db8:85a3:0:0:8a2e:370"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with valid IPv6 address that ends with double colons")
- fun testIsValidWithValidIPv6AddressThatEndsWithDoubleColons() {
- val ipString = "2001:db8:85a3:8a2e::"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with all number values")
- fun testIsValidWithAllNumberValues() {
- val ipString = "123:456:7890::"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with valid lowercase hexidecimal letters")
- fun testIsValidWithValidLowercaseHexidecimalLetters() {
- val ipString = "abcd:ef12:3456::"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with valid uppercase hexidecimal letters")
- fun testIsValidWithValidUppercaseHexidecimalLetters() {
- val ipString = "ABCD:EF12:3456::"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid uppercase hexidecimal letters")
- fun testIsValidWithInvalidUppercaseHexidecimalLetters() {
- val ipString = "ABCD:EFG2:3456::"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid hexidecimal letters")
- fun testIsValidWithInvalidLowercaseHexidecimalLetters() {
- val ipString = "-C=[]:E{12g:3456"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid digit")
- fun testIsValidWithInvalidDigit1() {
- val ipString = "aC=[]:E{12g:3456"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid digit")
- fun testIsValidWithInvalidDigit2() {
- val ipString = "aCd[:E{12g:3456"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid digit")
- fun testIsValidWithInvalidDigit3() {
- val ipString = "aCd:E{2g:3456"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address that has double colon and 8 groups")
- fun testIsValidWithInvalidIPv6AddressThatHasDoubleColonAnd8Groups() {
- val ipString = "dead:beef:85a3::0:0:8a2e:370"
- val bytes = toBytes(ipString)
- assertEquals(16, bytes.size)
- assertTrue(isValid(ipString))
- }
-
- @Test
- @DisplayName("Test isValid with invalid IPv6 address that has only has 7 groups")
- fun testIsValidWithInvalidIPv6AddressThatHasOnlyHas7Groups() {
- val ipString = "dead:beef:85a3:0:0:8a2e:370"
- val bytes = toBytes(ipString)
- assertEquals(0, bytes.size)
- assertFalse(isValid(ipString))
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.kt
deleted file mode 100644
index 9f20b62..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/LongUriSerializerTest.kt
+++ /dev/null
@@ -1,1009 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.uri.serializer
-
-import org.eclipse.uprotocol.uri.validator.isEmpty
-import org.eclipse.uprotocol.uri.validator.isRemote
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-
-
-class LongUriSerializerTest {
- @Test
- @DisplayName("Test using the serializers")
- fun test_using_the_serializers() {
- val uri: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource { forRpcRequest("raise") }
- }
-
- val strUri: String = LongUriSerializer.INSTANCE.serialize(uri)
- assertEquals("/hartley//rpc.raise", strUri)
- val uri2: UUri = LongUriSerializer.INSTANCE.deserialize(strUri)
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri that is empty string")
- fun test_parse_protocol_uri_when_is_empty_string() {
- val uri = ""
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with schema and slash")
- fun test_parse_protocol_uri_with_schema_and_slash() {
- val uri = "/"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.hasAuthority())
- assertTrue(uuri.isEmpty())
- assertFalse(uuri.hasResource())
- assertFalse(uuri.hasEntity())
- val uri2: String = LongUriSerializer.INSTANCE.serialize(uUri { })
- assertTrue(uri2.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with schema and double slash")
- fun test_parse_protocol_uri_with_schema_and_double_slash() {
- val uri = "//"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.hasAuthority())
- assertFalse(uuri.hasResource())
- assertFalse(uuri.hasEntity())
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with schema and 3 slash and something")
- fun test_parse_protocol_uri_with_schema_and_3_slash_and_something() {
- val uri = "///body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.hasAuthority())
- assertFalse(uuri.hasResource())
- assertFalse(uuri.hasEntity())
- assertTrue(uuri.isEmpty())
- assertNotEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with schema and 4 slash and something")
- fun test_parse_protocol_uri_with_schema_and_4_slash_and_something() {
- val uri = "////body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertFalse(uuri.hasResource())
- assertFalse(uuri.hasEntity())
- assertTrue(uuri.entity.name.isBlank())
- assertEquals(0, uuri.entity.versionMajor)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with schema and 5 slash and something")
- fun test_parse_protocol_uri_with_schema_and_5_slash_and_something() {
- val uri = "/////body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertFalse(uuri.hasResource())
- assertFalse(uuri.hasEntity())
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with schema and 6 slash and something")
- fun test_parse_protocol_uri_with_schema_and_6_slash_and_something() {
- val uri = "//////body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service no version")
- fun test_parse_protocol_uri_with_local_service_no_version() {
- val uri = "/body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals(0, uuri.entity.versionMinor)
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service with version")
- fun test_parse_protocol_uri_with_local_service_with_version() {
- val uri = "/body.access/1"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(1, uuri.entity.versionMajor)
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service no version with resource name only")
- fun test_parse_protocol_uri_with_local_service_no_version_with_resource_name_only() {
- val uri = "/body.access//door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals(0, uuri.entity.versionMinor)
- assertEquals("door", uuri.resource.name)
- assertTrue(uuri.resource.instance.isEmpty())
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service with version with resource name only")
- fun test_parse_protocol_uri_with_local_service_with_version_with_resource_name_only() {
- val uri = "/body.access/1/door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertTrue(uuri.resource.instance.isEmpty())
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service no version with resource and instance only")
- fun test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance() {
- val uri = "/body.access//door.front_left"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service with version with resource and instance only")
- fun test_parse_protocol_uri_with_local_service_with_version_with_resource_with_getMessage() {
- val uri = "/body.access/1/door.front_left"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service no version with resource with instance and message")
- fun test_parse_protocol_uri_with_local_service_no_version_with_resource_with_instance_and_getMessage() {
- val uri = "/body.access//door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with local service with version with resource with instance and message")
- fun test_parse_protocol_uri_with_local_service_with_version_with_resource_with_instance_and_getMessage() {
- val uri = "/body.access/1/door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse uProtocol RPC uri with local service no version")
- fun test_parse_protocol_rpc_uri_with_local_service_no_version() {
- val uri = "/petapp//rpc.response"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("petapp", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("rpc", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("response", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol RPC uri with local service with version")
- fun test_parse_protocol_rpc_uri_with_local_service_with_version() {
- val uri = "/petapp/1/rpc.response"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("petapp", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("rpc", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("response", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service , name with device and domain")
- fun test_parse_protocol_uri_with_remote_service_only_device_and_domain() {
- val uri = "//VCU.MY_CAR_VIN"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service only device and cloud domain")
- fun test_parse_protocol_uri_with_remote_service_only_device_and_cloud_domain() {
- val uri = "//cloud.uprotocol.example.com"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.hasEntity())
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service no version")
- fun test_parse_protocol_uri_with_remote_service_no_version() {
- val uri = "//VCU.MY_CAR_VIN/body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote cloud service no version")
- fun test_parse_protocol_uri_with_remote_cloud_service_no_version() {
- val uri = "//cloud.uprotocol.example.com/body.access"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service with version")
- fun test_parse_protocol_uri_with_remote_service_with_version() {
- val uri = "//VCU.MY_CAR_VIN/body.access/1"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote cloud service with version")
- fun test_parse_protocol_uri_with_remote_cloud_service_with_version() {
- val uri = "//cloud.uprotocol.example.com/body.access/1"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertFalse(uuri.hasResource())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service no version with resource name only")
- fun test_parse_protocol_uri_with_remote_service_no_version_with_resource_name_only() {
- val uri = "//VCU.MY_CAR_VIN/body.access//door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertTrue(uuri.resource.instance.isEmpty())
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource name only")
- fun test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_name_only() {
- val uri = "//cloud.uprotocol.example.com/body.access//door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertTrue(uuri.resource.instance.isEmpty())
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service with version with resource name only")
- fun test_parse_protocol_uri_with_remote_service_with_version_with_resource_name_only() {
- val uri = "//VCU.MY_CAR_VIN/body.access/1/door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertTrue(uuri.resource.instance.isEmpty())
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource name only")
- fun test_parse_protocol_uri_with_remote_service_cloud_with_version_with_resource_name_only() {
- val uri = "//cloud.uprotocol.example.com/body.access/1/door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertTrue(uuri.resource.instance.isEmpty())
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance no message")
- fun test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_no_getMessage() {
- val uri = "//VCU.MY_CAR_VIN/body.access//door.front_left"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance no message")
- fun test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_no_getMessage() {
- val uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service no version with resource and instance and message")
- fun test_parse_protocol_uri_with_remote_service_no_version_with_resource_and_instance_and_getMessage() {
- val uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote cloud service no version with resource and instance and message")
- fun test_parse_protocol_uri_with_remote_cloud_service_no_version_with_resource_and_instance_and_getMessage() {
- val uri = "//cloud.uprotocol.example.com/body.access//door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service with version with resource and instance and message")
- fun test_parse_protocol_uri_with_remote_service_with_version_with_resource_and_instance_and_getMessage() {
- val uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU.MY_CAR_VIN", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote cloud service with version with resource and instance and message")
- fun test_parse_protocol_uri_with_remote_cloud_service_with_version_with_resource_and_instance_and_getMessage() {
- val uri = "//cloud.uprotocol.example.com/body.access/1/door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("cloud.uprotocol.example.com", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse uProtocol uri with microRemote service with version with resource with message when there is only device, no domain")
- fun test_parse_protocol_uri_with_remote_service_with_version_with_resource_with_message_device_no_domain() {
- val uri = "//VCU/body.access/1/door.front_left"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("VCU", uuri.authority.name)
- assertFalse(uuri.authority.name.isEmpty())
- assertEquals("body.access", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol RPC uri with microRemote service no version")
- fun test_parse_protocol_rpc_uri_with_remote_service_no_version() {
- val uri = "//bo.cloud/petapp//rpc.response"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("bo.cloud", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("petapp", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("rpc", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("response", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test parse uProtocol RPC uri with microRemote service with version")
- fun test_parse_protocol_rpc_uri_with_remote_service_with_version() {
- val uri = "//bo.cloud/petapp/1/rpc.response"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("bo.cloud", uuri.authority.name)
- assertFalse(uuri.authority.name.isBlank())
- assertEquals("petapp", uuri.entity.name)
- assertNotEquals(0, uuri.entity.versionMajor)
- assertEquals(1, uuri.entity.versionMajor)
- assertEquals("rpc", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("response", uuri.resource.instance)
- assertTrue(uuri.resource.message.isEmpty())
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an empty URI Object")
- fun test_build_protocol_uri_from__uri_when__uri_isEmpty() {
- val uuri: UUri = uUri { }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI object with an empty USE")
- fun test_build_protocol_uri_from__uri_when__uri_has_empty_use() {
- val use: UEntity = uEntity { }
- val uuri: UUri = uUri {
- authority = uAuthority { }
- entity = use
- resource = uResource { name = "door" }
- }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/////door", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version() {
- val uuri: UUri = uUri { entity = uEntity { name = "body.access" } }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource { }
- }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access/1", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service no version with resource")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource() {
- val use: UEntity = uEntity {
- name = "body.access"
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource { name = "door" }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access//door", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a local authority with service and version with resource")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource { name = "door" }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access/1/door", uProtocolUri)
- }
-
- @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")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_no_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access//door.front_left", uProtocolUri)
- }
-
- @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")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_no_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- }
- }
-
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access/1/door.front_left", uProtocolUri)
- }
-
- @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")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_no_version_with_resource_with_instance_with_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access//door.front_left#Door", uProtocolUri)
- }
-
- @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")
- fun test_build_protocol_uri_from__uri_when__uri_has_local_authority_service_and_version_with_resource_with_instance_with_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("/body.access/1/door.front_left#Door", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version() {
- val use: UEntity = uEntity { name = "body.access" }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//vcu.my_car_vin/body.access", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- entity = use
- authority = uAuthority {
- name = "vcu.my_car_vin"
-
- }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//vcu.my_car_vin/body.access/1", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote cloud authority with service and version")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "cloud.uprotocol.example.com" }
- entity = use
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//cloud.uprotocol.example.com/body.access/1", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service and version with resource")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- resource = uResource { name = "door" }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from an URI Object with a microRemote authority with service no version with resource")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource() {
- val use: UEntity = uEntity {
- name = "body.access"
-
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- resource = uResource { name = "door" }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//vcu.my_car_vin/body.access//door", uProtocolUri)
- }
-
- @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")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_no_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- 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 microRemote cloud authority with service and version with resource with instance no message")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_cloud_authority_service_and_version_with_resource_with_instance_no_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "cloud.uprotocol.example.com" }
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- 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 microRemote authority with service no version with resource with instance no message")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_no_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//vcu.my_car_vin/body.access//door.front_left", uProtocolUri)
- }
-
- @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")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_and_version_with_resource_with_instance_and_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- 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 microRemote authority with service no version with resource with instance and message")
- fun test_build_protocol_uri_from__uri_when__uri_has_remote_authority_service_no_version_with_resource_with_instance_and_getMessage() {
- val use: UEntity = uEntity {
- name = "body.access"
- }
- val uuri: UUri = uUri {
- authority = uAuthority { name = "vcu.my_car_vin" }
- entity = use
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uuri)
- assertEquals("//vcu.my_car_vin/body.access//door.front_left#Door", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is local")
- fun test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_local() {
- val use: UEntity = uEntity {
- name = "petapp"
- versionMajor = 1
- }
- val uResource: UResource = uResource {
- name = "rpc"
- instance = "response"
- }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uUri {
- entity = use
- resource = uResource
- })
- assertEquals("/petapp/1/rpc.response", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI for the source part of an RPC request, where the source is microRemote")
- fun test_build_protocol_uri_for_source_part_of_rpc_request_where_source_is_remote() {
- val uAuthority: UAuthority = uAuthority { name = "cloud.uprotocol.example.com" }
- val use: UEntity = uEntity {
- name = "petapp"
- }
- val uResource: UResource = uResource {
- name = "rpc"
- instance = "response"
- }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uUri {
- authority = uAuthority
- entity = use
- resource = uResource
- })
- assertEquals("//cloud.uprotocol.example.com/petapp//rpc.response", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a uProtocol URI from the parts of URI Object with a microRemote authority with service and version with resource")
- fun test_build_protocol_uri_from__uri_parts_when__uri_has_remote_authority_service_and_version_with_resource() {
- val uAuthority: UAuthority = uAuthority { name = "vcu.my_car_vin" }
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uResource: UResource = uResource { name = "door" }
- val uProtocolUri: String = LongUriSerializer.INSTANCE.serialize(uUri {
- authority = uAuthority
- entity = use
- resource = uResource
- })
- assertEquals("//vcu.my_car_vin/body.access/1/door", uProtocolUri)
- }
-
- @Test
- @DisplayName("Test Create a custom URI using no scheme")
- fun test_custom_scheme_no_scheme() {
- val uAuthority: UAuthority = uAuthority { name = "vcu.my_car_vin" }
- val use: UEntity = uEntity {
- name = "body.access"
- versionMajor = 1
- }
- val uResource: UResource = uResource { name = "door" }
- val ucustomUri: String = LongUriSerializer.INSTANCE.serialize(uUri {
- authority = uAuthority
- entity = use
- resource = uResource
- }
-
- )
- assertEquals("//vcu.my_car_vin/body.access/1/door", ucustomUri)
- }
-
- @Test
- @DisplayName("Test parse local uProtocol uri with custom scheme")
- fun test_parse_local_protocol_uri_with_custom_scheme() {
- val uri = "custom:/body.access//door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertFalse(uuri.authority.isRemote())
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertFalse(uuri.resource.instance.isEmpty())
- assertEquals("front_left", uuri.resource.instance)
- assertFalse(uuri.resource.message.isEmpty())
- assertEquals("Door", uuri.resource.message)
- }
-
- @Test
- @DisplayName("Test parse microRemote uProtocol uri with custom scheme")
- fun test_parse_remote_protocol_uri_with_custom_scheme() {
- val uri = "custom://vcu.vin/body.access//door.front_left#Door"
- val uri2 = "//vcu.vin/body.access//door.front_left#Door"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- assertTrue(uuri.authority.isRemote())
- assertEquals("vcu.vin", uuri.authority.name)
- assertEquals("body.access", uuri.entity.name)
- assertEquals(0, uuri.entity.versionMajor)
- assertEquals("door", uuri.resource.name)
- assertEquals("front_left", uuri.resource.instance)
- assertEquals("Door", uuri.resource.message)
- assertEquals(uri2, LongUriSerializer.INSTANCE.serialize(uuri))
- }
-}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.kt
deleted file mode 100644
index 7e8d632..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/MicroUriSerializerTest.kt
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.uri.serializer
-
-import com.google.protobuf.ByteString
-import org.eclipse.uprotocol.uri.serializer.IpAddress.toBytes
-import org.eclipse.uprotocol.uri.validator.isEmpty
-import org.eclipse.uprotocol.uri.validator.isMicroForm
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-import java.net.InetAddress
-import java.net.UnknownHostException
-
-
-class MicroUriSerializerTest {
- @Test
- @DisplayName("Test serialize and deserialize empty content")
- fun test_empty() {
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(UUri.getDefaultInstance())
- assertEquals(bytes.size, 0)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertTrue(uri2.isEmpty())
- }
-
- @Test
- @DisplayName("Test happy path Byte serialization of local UUri")
- fun test_serialize_uri() {
- val uri: UUri = uUri {
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { from(19999) }
- }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertTrue(uri.isMicroForm())
- assertTrue(bytes.isNotEmpty())
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test Serialize a remote UUri to micro without the address")
- fun test_serialize_remote_uri_without_address() {
- val uri: UUri = uUri {
- authority = uAuthority { name = "vcu.vin" }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { id = 19999 }
- }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertTrue(bytes.isEmpty())
- }
-
- @Test
- @DisplayName("Test serialize Uri missing uE ID")
- fun test_serialize_uri_missing_ids() {
- val uri: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource { forRpcResponse() }
- }
-
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertTrue(bytes.isEmpty())
- }
-
- @Test
- @DisplayName("Test serialize Uri missing resource")
- fun test_serialize_uri_missing_resource_id() {
- val uri: UUri = uUri { entity = uEntity { name = "hartley" } }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertTrue(bytes.isEmpty())
- }
-
- @Test
- @DisplayName("Test deserialize bad micro uri - length")
- fun test_deserialize_bad_microuri_length() {
- var badMicroUUri = byteArrayOf(0x1, 0x0, 0x0, 0x0, 0x0)
- var uuri: UUri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- badMicroUUri = byteArrayOf(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
- uuri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test deserialize bad micro uri - not version 1")
- fun test_deserialize_bad_microuri_not_version_1() {
- val badMicroUUri = byteArrayOf(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
- val uuri: UUri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test deserialize bad micro uri - not valid address type")
- fun test_deserialize_bad_microuri_not_valid_address_type() {
- val badMicroUUri = byteArrayOf(0x1, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
- val uuri: UUri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test deserialize bad micro uri - valid address type and invalid length")
- fun test_deserialize_bad_microuri_valid_address_type_invalid_length() {
- var badMicroUUri = byteArrayOf(0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
- var uuri: UUri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- badMicroUUri = byteArrayOf(0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
- uuri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- badMicroUUri = byteArrayOf(0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
- uuri = MicroUriSerializer.INSTANCE.deserialize(badMicroUUri)
- assertTrue(uuri.isEmpty())
- }
-
- @Test
- @DisplayName("Test serialize with good IPv4 based authority")
- @Throws(UnknownHostException::class)
- fun test_serialize_good_ipv4_based_authority() {
- val uri: UUri = uUri {
- authority = uAuthority { ip = ByteString.copyFrom(InetAddress.getByName("10.0.3.3").address) }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { forRpcRequest( id = 99) }
- }
-
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertTrue(bytes.isNotEmpty())
- assertTrue(uri.isMicroForm())
- assertTrue(uri2.isMicroForm())
- assertEquals(uri.toString(), uri2.toString())
- assertTrue(uri == uri2)
- }
-
- @Test
- @DisplayName("Test serialize with good IPv4 based authority and the uEntity major version is missing")
- fun test_serialize_good_ipv4_based_authority_missing_major_version() {
- val uri: UUri = uUri {
- authority = uAuthority { ip = ByteString.copyFrom(toBytes("192.168.1.100")) }
- entity = uEntity { id = 29999 }
- resource = uResource { forRpcResponse() }
- }
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertEquals(uri2.entity.versionMajor, 0)
- }
-
- @Test
- @DisplayName("Test serialize without uauthority ip or id")
- fun test_serialize_without_uauthority_ip_or_id() {
- val uri: UUri = uUri {
- authority = uAuthority { name = "vcu.vin" }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { id = 19999 }
- }
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertTrue(bytes.isEmpty())
- }
-
- @Test
- @DisplayName("Test serialize with id that is out of range")
- fun test_serialize_id_out_of_range() {
- val byteArray = ByteArray(258)
- for (i in 0..255) {
- byteArray[i] = i.toByte()
- }
- val uri: UUri = uUri {
- authority = uAuthority { ip = ByteString.copyFrom(byteArray) }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { from(19999) }
- }
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertTrue(bytes.isEmpty())
- }
-
- @Test
- @DisplayName("Test serialize with good IPv6 based authority")
- @Throws(UnknownHostException::class)
- fun test_serialize_good_ipv6_based_authority() {
- val uri: UUri = uUri {
- authority = uAuthority {
- ip = ByteString.copyFrom(
- InetAddress.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334").address
- )
- }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
-
- resource = uResource { from(19999) }
- }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertTrue(uri.isMicroForm())
- assertTrue(bytes.isNotEmpty())
- assertTrue(uri == uri2)
- }
-
- @Test
- @DisplayName("Test serialize with ID based authority")
- fun test_serialize_id_based_authority() {
- val size = 13
- val byteArray = ByteArray(size)
- // Assign values to the elements of the byte array
- for (i in 0 until size) {
- byteArray[i] = i.toByte()
- }
- val uri: UUri = uUri {
- authority = uAuthority { id = ByteString.copyFrom(byteArray) }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { from(19999) }
- }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertTrue(uri.isMicroForm())
- assertTrue(bytes.isNotEmpty())
- assertTrue(uri == uri2)
- }
-
- @Test
- @DisplayName("Test serialize with bad length IP based authority")
- @Throws(UnknownHostException::class)
- fun test_serialize_bad_length_ip_based_authority() {
- val byteArray = byteArrayOf(127, 1, 23, 123, 12, 6)
- val uri: UUri = uUri {
- authority = uAuthority {
- ip = ByteString.copyFrom(byteArray)
- }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { from(19999) }
- }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertTrue(bytes.isEmpty())
- }
-
- @Test
- @DisplayName("Test serialize with ID based authority")
- fun test_serialize_id_size_255_based_authority() {
- val size = 129
- val byteArray = ByteArray(size)
- // Assign values to the elements of the byte array
- for (i in 0 until size) {
- byteArray[i] = i.toByte()
- }
- val uri: UUri = uUri {
- authority = uAuthority { id = ByteString.copyFrom(byteArray) }
- entity = uEntity {
- id = 29999
- versionMajor = 254
- }
- resource = uResource { from(19999) }
- }
-
- val bytes: ByteArray = MicroUriSerializer.INSTANCE.serialize(uri)
- assertEquals(bytes.size, 9 + size)
- val uri2: UUri = MicroUriSerializer.INSTANCE.deserialize(bytes)
- assertTrue(uri.isMicroForm())
- assertTrue(uri == uri2)
- }
-}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.kt
deleted file mode 100644
index 4dcaa1f..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/ShortUriSerializerTest.kt
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
-* Copyright (c) 2024 General Motors GTO LLC
-*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*
-* SPDX-FileType: SOURCE
-* SPDX-FileCopyrightText: 2024 General Motors GTO LLC
-* SPDX-License-Identifier: Apache-2.0
-*/
-
-package org.eclipse.uprotocol.uri.serializer
-
-import com.google.protobuf.ByteString
-import org.eclipse.uprotocol.uri.serializer.IpAddress.toBytes
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-
-
-class ShortUriSerializerTest {
- @Test
- @DisplayName("Test serialize with empty uri")
- fun testSerializeWithEmptyUri() {
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(UUri.getDefaultInstance())
- assertEquals("", strUri)
- }
-
-
- @Test
- @DisplayName("Test Creating and using the ShortUriSerializer")
- fun testCreatingShortUriSerializer() {
- val uri: UUri = uUri {
- entity = uEntity{ id = 1; versionMajor = 1 }
- resource = uResource{ forRpcResponse() }
- }
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals("/1/1/0", strUri)
- val uri2: UUri = ShortUriSerializer.INSTANCE.deserialize(strUri)
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test Creating and using the ShortUriSerializer with a method")
- fun testCreatingShortUriSerializerWithMethod() {
- val uri: UUri = uUri {
- entity = uEntity{ id = 1; versionMajor = 1 }
- resource = uResource { forRpcRequest(id = 10) }
- }
-
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals("/1/1/10", strUri)
- val uri2: UUri = ShortUriSerializer.INSTANCE.deserialize(strUri)
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test Creating and using the ShortUriSerializer with a topic")
- fun testCreatingShortUriSerializerWithTopic() {
- val uri: UUri = uUri {
- entity = uEntity{ id = 1; versionMajor = 1 }
- resource = uResource { from(20000) }
- }
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals("/1/1/20000", strUri)
- val uri2: UUri = ShortUriSerializer.INSTANCE.deserialize(strUri)
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test Creating and using the ShortUriSerializer with id authority")
- fun testCreatingShortUriSerializerWithAuthority() {
- val uri: UUri = uUri {
- entity = uEntity{ id = 1; versionMajor = 1 }
- authority = uAuthority { id = ByteString.copyFromUtf8("19UYA31581L000000")}
- resource = uResource { from(20000) }
- }
-
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals("//19UYA31581L000000/1/1/20000", strUri)
- val uri2: UUri = ShortUriSerializer.INSTANCE.deserialize(strUri)
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test Creating and using the ShortUriSerializer with ip authority")
- fun testCreatingShortUriSerializerWithIpAuthority() {
- val uri: UUri = uUri {
- entity = uEntity{ id = 1; versionMajor = 1 }
- authority = uAuthority { ip = ByteString.copyFrom(toBytes("192.168.1.100")) }
- resource = uResource { from(20000) }
- }
-
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals("//192.168.1.100/1/1/20000", strUri)
- val uri2: UUri = ShortUriSerializer.INSTANCE.deserialize(strUri)
- assertEquals(uri, uri2)
- }
-
- @Test
- @DisplayName("Test short serializing a URI that doesn't have a resource")
- fun testShortSerializingUriWithoutResource() {
- val uri = uUri {
- entity = uEntity { id = 1; versionMajor = 1 }
- }
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals(strUri, "/1/1")
- }
-
- @Test
- @DisplayName("Test short serializing a URI that have a negative number for uEntity version major")
- fun testShortSerializingUriWithNegativeVersionMajor() {
- val uri: UUri = uUri {
- entity = uEntity { id = 1; versionMajor = -1 }
- resource = uResource { from(20000) }
- }
- val strUri: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals(strUri, "/1//20000")
- }
-
- @Test
- @DisplayName("Test short deserialize an empty URI")
- fun testShortDeserializeEmptyUri() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short deserialize of a valid URI with scheme")
- fun testShortDeserializeUriWithSchemeAndAuthority() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("up://mypc/1/1/1")
- assertTrue(uri.hasAuthority())
- assertEquals(uri.authority.id, ByteString.copyFromUtf8("mypc"))
- assertFalse(uri.authority.hasName())
- assertFalse(uri.authority.hasIp())
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertEquals(uri.entity.versionMajor, 1)
- assertTrue(uri.hasResource())
- assertEquals(uri.resource.id, 1)
- }
-
- @Test
- @DisplayName("Test short deserialize of a valid URI without scheme")
- fun testShortDeserializeUriWithoutScheme() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//mypc/1/1/1")
- assertTrue(uri.hasAuthority())
- assertEquals(uri.authority.id, ByteString.copyFromUtf8("mypc"))
- assertFalse(uri.authority.hasName())
- assertFalse(uri.authority.hasIp())
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertEquals(uri.entity.versionMajor, 1)
- assertTrue(uri.hasResource())
- assertEquals(uri.resource.id, 1)
- }
-
- @Test
- @DisplayName("Test short deserialize a uri that only contains //")
- fun testShortDeserializeUriWithOnlyAuthority() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short deserialize a uri with scheme and only contains //")
- fun testShortDeserializeUriWithSchemeAndOnlyAuthority() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("up://")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short serialize with UAuthority ip address that is invalid")
- fun testShortSerializeWithInvalidIpAddress() {
- val uri = UUri.newBuilder()
- .setEntity(UEntity.newBuilder().setId(1).setVersionMajor(1))
- .setAuthority(UAuthority.newBuilder().setIp(ByteString.copyFromUtf8("34823748273")))
- .build()
- val uriString: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals(uriString, "")
- }
-
- @Test
- @DisplayName("Test short serialize with UAuthority that only have name and not ip or id")
- fun testShortSerializeWithAuthorityOnlyName() {
- val uri = UUri.newBuilder()
- .setEntity(UEntity.newBuilder().setId(1).setVersionMajor(1))
- .setAuthority(UAuthority.newBuilder().setName("mypc"))
- .build()
- val uriString: String = ShortUriSerializer.INSTANCE.serialize(uri)
- assertEquals(uriString, "")
- }
-
- @Test
- @DisplayName("Test short deserialize of a local URI that has too many parts")
- fun testShortDeserializeLocalUriWithTooManyParts() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("/1/1/1/1")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short deserialize of a local URI that only has 2 parts")
- fun testShortDeserializeLocalUriWithOnlyTwoParts() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("/1/1")
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertEquals(uri.entity.versionMajor, 1)
- }
-
- @Test
- @DisplayName("Test short deserialize of a local URI that has 2 parts")
- fun testShortDeserializeLocalUriWithThreeParts() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("/1")
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertFalse(uri.hasResource())
- }
-
- @Test
- @DisplayName("Test short deserialize with a blank authority")
- fun testShortDeserializeWithBlankAuthority() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("///1/1/1")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority that is an IP address and too many parts in the uri")
- fun testShortDeserializeWithRemoteAuthorityIpAndTooManyParts() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//192.168.1.100/1/1/1/1")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority that is an IP address and right number of parts")
- fun testShortDeserializeWithRemoteAuthorityIpAndRightNumberOfParts() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//192.168.1.100/1/1/1")
- assertTrue(uri.hasAuthority())
- assertTrue(uri.authority.hasIp())
- assertTrue(uri.authority.ip == ByteString.copyFrom(toBytes("192.168.1.100")))
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertEquals(uri.entity.versionMajor, 1)
- assertTrue(uri.hasResource())
- assertEquals(uri.resource.id, 1)
- }
-
-
- @Test
- @DisplayName("Test short deserialize with a remote authority that is an IP address but missing resource")
- fun testShortDeserializeWithRemoteAuthorityIpAddressMissingResource() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//192.168.1.100/1/1")
- assertTrue(uri.hasAuthority())
- assertTrue(uri.authority.hasIp())
- assertTrue(uri.authority.ip == ByteString.copyFrom(toBytes("192.168.1.100")))
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertEquals(uri.entity.versionMajor, 1)
- assertFalse(uri.hasResource())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority that is an IP address but missing resource and major version")
- fun testShortDeserializeWithRemoteAuthorityIpAddressMissingResourceAndVersionMajor() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//192.168.1.100/1")
- assertTrue(uri.hasAuthority())
- assertTrue(uri.authority.hasIp())
- assertTrue(uri.authority.ip == ByteString.copyFrom(toBytes("192.168.1.100")))
- assertTrue(uri.hasEntity())
- assertEquals(uri.entity.id, 1)
- assertFalse(uri.entity.hasVersionMajor())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority that is an IP address but missing resource and major version")
- fun testShortDeserializeWithRemoteAuthorityIpAddressMissingResourceAndVersionMajorAndUeId() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//192.168.1.100//")
- assertTrue(uri.hasAuthority())
- assertTrue(uri.authority.hasIp())
- assertTrue(uri.authority.ip == ByteString.copyFrom(toBytes("192.168.1.100")))
- assertFalse(uri.hasEntity())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority and blank ueversion and ueid")
- fun testShortDeserializeWithRemoteAuthorityAndBlankUeVersionAndUeId() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//mypc//1/")
- assertTrue(uri.hasAuthority())
- assertTrue(uri.authority.hasId())
- assertEquals(uri.authority.id, ByteString.copyFromUtf8("mypc"))
- assertTrue(uri.hasEntity())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority and missing the other parts")
- fun testShortDeserializeWithRemoteAuthorityAndMissingParts() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//mypc")
- assertTrue(uri.hasAuthority())
- assertTrue(uri.authority.hasId())
- assertEquals(uri.authority.id, ByteString.copyFromUtf8("mypc"))
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority and invalid characters for entity id and version")
- fun testShortDeserializeWithRemoteAuthorityAndInvalidEntityIdAndVersion() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//mypc/abc/def")
- assertEquals(uri, UUri.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test short deserialize with a remote authority and invalid characters for resource id")
- fun testShortDeserializeWithRemoteAuthorityAndInvalidResourceId() {
- val uri: UUri = ShortUriSerializer.INSTANCE.deserialize("//mypc/1/1/abc")
- assertEquals(uri.resource, UResource.getDefaultInstance())
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.kt
index 1768793..ed7699c 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/uri/serializer/UriSerializerTest.kt
@@ -1,189 +1,331 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uri.serializer
-import com.google.protobuf.ByteString
-import org.eclipse.uprotocol.UprotocolOptions
-import org.eclipse.uprotocol.core.usubscription.v3.USubscriptionProto
-import org.eclipse.uprotocol.uri.factory.UEntityFactory.fromProto
import org.eclipse.uprotocol.uri.validator.isEmpty
-import org.eclipse.uprotocol.uri.validator.isLongForm
-import org.eclipse.uprotocol.uri.validator.isMicroForm
-import org.eclipse.uprotocol.uri.validator.isShortForm
-import org.eclipse.uprotocol.v1.*
-import org.junit.jupiter.api.Assertions.*
+import org.eclipse.uprotocol.v1.UUri
+import org.eclipse.uprotocol.v1.uUri
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
-import java.net.InetAddress
class UriSerializerTest {
@Test
- @DisplayName("Test building uSubscription Update Notification topic and comparing long, short, and micro URIs")
- fun test_build_resolved_full_information_compare() {
- val descriptor = USubscriptionProto.getDescriptor().services[0]
+ @DisplayName("Test using the serializers")
+ fun test_using_the_serializers() {
+ val uri = UUri.newBuilder()
+ .setAuthorityName("myAuthority")
+ .setUeId(1)
+ .setUeVersionMajor(2)
+ .setResourceId(3)
+ .build()
- val entity = fromProto(descriptor)
+ val serializedUri: String = uri.serialize()
+ assertEquals("//myAuthority/1/2/3", serializedUri)
+ }
+
+ @Test
+ @DisplayName("Test deserializing an empty UUri")
+ fun test_deserializing_an_empty_UUri() {
+ val uri: UUri = "".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+
+ @Test
+ @DisplayName("Test deserializing a blank UUri")
+ fun test_deserializing_a_blank_UUri() {
+ val uri: UUri = " ".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing with a valid URI that has scheme")
+ fun test_deserializing_with_a_valid_URI_that_has_scheme() {
+ val uri: UUri = "up://myAuthority/1/2/3".deserializeAsUUri()
+ assertEquals("myAuthority", uri.authorityName)
+ assertEquals(1, uri.ueId)
+ assertEquals(2, uri.ueVersionMajor)
+ assertEquals(3, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test deserializing with a valid URI that has scheme but nothing else")
+ fun test_deserializing_with_a_valid_URI_that_has_scheme_but_nothing_else() {
+ val uri: UUri = "up://".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a valid UUri with all fields")
+ fun test_deserializing_a_valid_UUri_with_all_fields() {
+ val uri: UUri = "//myAuthority/1/2/3".deserializeAsUUri()
+ assertEquals("myAuthority", uri.authorityName)
+ assertEquals(1, uri.ueId)
+ assertEquals(2, uri.ueVersionMajor)
+ assertEquals(3, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test deserializing a valid UUri with only authority")
+ fun test_deserializing_a_valid_UUri_with_only_authority() {
+ val uri: UUri = "//myAuthority".deserializeAsUUri()
+ assertEquals("myAuthority", uri.authorityName)
+ assertEquals(0, uri.ueId)
+ assertEquals(0, uri.ueVersionMajor)
+ assertEquals(0, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test deserializing a valid UUri with only authority and ueId")
+ fun test_deserializing_a_valid_UUri_with_only_authority_and_ueId() {
+ val uri: UUri = "//myAuthority/1".deserializeAsUUri()
+ assertEquals("myAuthority", uri.authorityName)
+ assertEquals(1, uri.ueId)
+ assertEquals(0, uri.ueVersionMajor)
+ assertEquals(0, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test deserializing a valid UUri with only authority, ueId and ueVersionMajor")
+ fun test_deserializing_a_valid_UUri_with_only_authority_ueId_and_ueVersionMajor() {
+ val uri: UUri = "//myAuthority/1/2".deserializeAsUUri()
+ assertEquals("myAuthority", uri.authorityName)
+ assertEquals(1, uri.ueId)
+ assertEquals(2, uri.ueVersionMajor)
+ assertEquals(0, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with invalid characters at the beginning")
+ fun test_deserializing_a_string_with_invalid_characters() {
+ val uri: UUri = "$$".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with names instead of ids for UeId")
+ fun test_deserializing_a_string_with_names_instead_of_ids_for_UeId() {
+ val uri: UUri = "//myAuthority/myUeId/2/3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with names instead of ids for UeVersionMajor")
+ fun test_deserializing_a_string_with_names_instead_of_ids_for_UeVersionMajor() {
+ val uri: UUri = "//myAuthority/1/myUeVersionMajor/3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with names instead of ids for ResourceId")
+ fun test_deserializing_a_string_with_names_instead_of_ids_for_ResourceId() {
+ val uri: UUri = "//myAuthority/1/2/myResourceId".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string without authority")
+ fun test_deserializing_a_string_without_authority() {
+ val uri: UUri = "/1/2/3".deserializeAsUUri()
+ assertEquals(1, uri.ueId)
+ assertEquals(2, uri.ueVersionMajor)
+ assertEquals(3, uri.resourceId)
+ assertTrue(uri.authorityName.isBlank())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string without authority and ResourceId")
+ fun test_deserializing_a_string_without_authority_and_ResourceId() {
+ val uri: UUri = "/1/2".deserializeAsUUri()
+ assertEquals(1, uri.ueId)
+ assertEquals(2, uri.ueVersionMajor)
+ assertEquals(0, uri.resourceId)
+ assertTrue(uri.authorityName.isBlank())
+ }
- val options = descriptor.options
+ @Test
+ @DisplayName("Test deserializing a string without authority, ResourceId and UeVersionMajor")
+ fun test_deserializing_a_string_without_authority_ResourceId_and_UeVersionMajor() {
+ val uri: UUri = "/1".deserializeAsUUri()
+ assertEquals(1, uri.ueId)
+ assertEquals(0, uri.ueVersionMajor)
+ assertEquals(0, uri.resourceId)
+ assertTrue(uri.authorityName.isBlank())
+ }
- val resource = options.getExtension(UprotocolOptions.notificationTopic).filter { topic ->
- topic.name.contains("SubscriptionChange")
- }.map { topic ->
- uResource {
- from(topic)
- }
- }.first()
+ @Test
+ @DisplayName("Test deserializing a string with blank authority")
+ fun test_deserializing_a_string_with_blank_authority() {
+ val uri: UUri = "///2".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
- val uUri = uUri {
- this.entity = entity
- this.resource = resource
+ @Test
+ @DisplayName("Test deserializing a string with all the items are the wildcard values")
+ fun test_deserializing_a_string_with_all_the_items_are_the_wildcard_values() {
+ val uri: UUri = "//*/FFFF/ff/ffff".deserializeAsUUri()
+ assertEquals("*", uri.authorityName)
+ assertEquals(0xFFFF, uri.ueId)
+ assertEquals(0xFF, uri.ueVersionMajor)
+ assertEquals(0xFFFF, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with uEId() out of range")
+ fun test_deserializing_a_string_with_uEId_out_of_range() {
+ val uri: UUri = "/fffffffff/2/3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with uEVersionMajor out of range")
+ fun test_deserializing_a_string_with_uEVersionMajor_out_of_range() {
+ val uri: UUri = "/1/256/3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with resourceId out of range")
+ fun test_deserializing_a_string_with_resourceId_out_of_range() {
+ val uri: UUri = "/1/2/65536".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with negative uEId")
+ fun test_deserializing_a_string_with_negative_uEId() {
+ val uri: UUri = "/-1/2/3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with negative uEVersionMajor")
+ fun test_deserializing_a_string_with_negative_uEVersionMajor() {
+ val uri: UUri = "/1/-2/3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with negative resourceId")
+ fun test_deserializing_a_string_with_negative_resourceId() {
+ val uri: UUri = "/1/2/-3".deserializeAsUUri()
+ assertTrue(uri.isEmpty())
+ }
+
+ @Test
+ @DisplayName("Test deserializing a string with wildcard ResourceId")
+ fun test_deserializing_a_string_with_wildcard_resourceId() {
+ val uri: UUri = "/1/2/ffff".deserializeAsUUri()
+ assertEquals(1, uri.ueId)
+ assertEquals(2, uri.ueVersionMajor)
+ assertEquals(0xFFFF, uri.resourceId)
+ }
+
+ @Test
+ @DisplayName("Test serializing an Empty UUri")
+ fun test_serializing_an_empty_UUri() {
+ val uri = uUri { }
+ val serializedUri: String = uri.serialize()
+ assertTrue(serializedUri.isBlank())
+ }
+
+ @Test
+ @DisplayName("Test serializing a full UUri")
+ fun test_serializing_a_full_UUri() {
+ val uri = uUri {
+ authorityName = "myAuthority"
+ ueId = 1
+ ueVersionMajor = 2
+ resourceId = 3
}
+ val serializedUri: String = uri.serialize()
+ assertEquals("//myAuthority/1/2/3", serializedUri)
+ }
+
+ @Test
+ @DisplayName("Test serializing a UUri with only authority")
+ fun test_serializing_a_UUri_with_only_authority() {
+ val uri = uUri {
+ authorityName = "myAuthority"
- assertFalse(uUri.isEmpty())
- assertTrue(uUri.isMicroForm())
- assertTrue(uUri.isLongForm())
- assertTrue(uUri.isShortForm())
- val longUri: String = LongUriSerializer.INSTANCE.serialize(uUri)
- val microUri: ByteArray = MicroUriSerializer.INSTANCE.serialize(uUri)
- val shortUri: String = ShortUriSerializer.INSTANCE.serialize(uUri)
-
- assertEquals(longUri, "/core.usubscription/3/SubscriptionChange#Update")
- assertEquals(shortUri, "/0/3/32768")
- assertEquals(microUri.contentToString(), "[1, 0, -128, 0, 0, 0, 3, 0]")
- }
-
-
- @Test
- @DisplayName("Test building uSubscription Update Notification topic with IPv4 address UAuthority and comparing long, short, and micro URIs")
- fun test_build_resolved_full_information_compare_with_ipv4() {
- val descriptor = USubscriptionProto.getDescriptor().services[0]
- val entity = fromProto(descriptor)
- val options = descriptor.options
- val resource = options.getExtension(UprotocolOptions.notificationTopic).filter { topic ->
- topic.name.contains("SubscriptionChange")
- }.map { topic ->
- uResource {
- from(topic)
- }
- }.first()
-
- val uUri = uUri {
- this.entity = entity
- this.resource = resource
- authority = uAuthority {
- name = "vcu.veh.gm.com"
- ip = ByteString.copyFrom(InetAddress.getByName("192.168.1.100").address)
- }
}
+ val serializedUri: String = uri.serialize()
+ assertEquals("//myAuthority/0/0/0", serializedUri)
+ }
- assertFalse(uUri.isEmpty())
- assertTrue(uUri.isMicroForm())
- assertTrue(uUri.isLongForm())
- assertTrue(uUri.isShortForm())
- val longUri: String = LongUriSerializer.INSTANCE.serialize(uUri)
- val microUri: ByteArray = MicroUriSerializer.INSTANCE.serialize(uUri)
- val shortUri: String = ShortUriSerializer.INSTANCE.serialize(uUri)
-
- assertEquals(longUri, "//vcu.veh.gm.com/core.usubscription/3/SubscriptionChange#Update")
- assertEquals(shortUri, "//192.168.1.100/0/3/32768")
- assertEquals(microUri.contentToString(), "[1, 1, -128, 0, 0, 0, 3, 0, -64, -88, 1, 100]")
- }
-
- @Test
- @DisplayName("Test building uSubscription Update Notification topic with IPv6 address UAuthority and comparing long, short, and micro URIs")
- fun test_build_resolved_full_information_compare_with_ipv6() {
- val descriptor = USubscriptionProto.getDescriptor().services[0]
- val entity = fromProto(descriptor)
- val options = descriptor.options
- val resource = options.getExtension(UprotocolOptions.notificationTopic).filter { topic ->
- topic.name.contains("SubscriptionChange")
- }.map { topic ->
- uResource {
- from(topic)
- }
- }.first()
-
- val uUri = uUri {
- this.entity = entity
- this.resource = resource
- authority = uAuthority {
- name = "vcu.veh.gm.com"
- ip = ByteString.copyFrom(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334").address)
- }
+ @Test
+ @DisplayName("Test serializing a UUri with authority and ueId")
+ fun test_serializing_a_UUri_with_only_authority_and_ueId() {
+ val uri = uUri {
+ authorityName = "myAuthority"
+ ueId = 1
}
+ val serializedUri: String = uri.serialize()
+ assertEquals("//myAuthority/1/0/0", serializedUri)
+ }
+
+ @Test
+ @DisplayName("Test serializing a UUri with authority, ueId and ueVersionMajor")
+ fun test_serializing_a_UUri_with_only_authority_ueId_and_ueVersionMajor() {
+ val uri = uUri {
+ authorityName = "myAuthority"
+ ueId = 1
+ ueVersionMajor = 2
- assertFalse(uUri.isEmpty())
- assertTrue(uUri.isMicroForm())
- assertTrue(uUri.isLongForm())
- assertTrue(uUri.isShortForm())
- val longUri: String = LongUriSerializer.INSTANCE.serialize(uUri)
- val microUri: ByteArray = MicroUriSerializer.INSTANCE.serialize(uUri)
- val shortUri: String = ShortUriSerializer.INSTANCE.serialize(uUri)
-
- assertEquals(longUri, "//vcu.veh.gm.com/core.usubscription/3/SubscriptionChange#Update")
- assertEquals(shortUri, "//2001:db8:85a3:0:0:8a2e:370:7334/0/3/32768")
- assertEquals(
- microUri.contentToString(),
- "[1, 2, -128, 0, 0, 0, 3, 0, 32, 1, 13, -72, -123, -93, 0, 0, 0, 0, -118, 46, 3, 112, 115, 52]"
- )
- }
-
- @Test
- @DisplayName("Test building uSubscription Update Notification topic with id address UAuthority and comparing long, short, and micro URIs")
- fun test_build_resolved_full_information_compare_with_id() {
- val descriptor = USubscriptionProto.getDescriptor().services[0]
- val entity = fromProto(descriptor)
- val options = descriptor.options
-
- val resource = options.getExtension(UprotocolOptions.notificationTopic).filter { topic ->
- topic.name.contains("SubscriptionChange")
- }.map { topic ->
- uResource {
- from(topic)
- }
- }.first()
-
- val uUri = uUri {
- this.entity = entity
- this.resource = resource
- authority = uAuthority {
- name = "1G1YZ23J9P5800001.veh.gm.com"
- id = ByteString.copyFromUtf8("1G1YZ23J9P5800001")
- }
}
+ val serializedUri: String = uri.serialize()
+ assertEquals("//myAuthority/1/2/0", serializedUri)
+ }
+
+ @Test
+ @DisplayName("Test serializing a UUri with authority, ueId, ueVersionMajor and resourceId")
+ fun test_serializing_a_UUri_with_only_authority_ueId_ueVersionMajor_and_resourceId() {
+ val uri = uUri {
+ authorityName = "myAuthority"
+ ueId = 1
+ ueVersionMajor = 2
+ resourceId = 3
- assertFalse(uUri.isEmpty())
- assertTrue(uUri.isMicroForm())
- assertTrue(uUri.isLongForm())
- assertTrue(uUri.isShortForm())
- val longUri: String = LongUriSerializer.INSTANCE.serialize(uUri)
- val microUri: ByteArray = MicroUriSerializer.INSTANCE.serialize(uUri)
- val shortUri: String = ShortUriSerializer.INSTANCE.serialize(uUri)
-
- assertEquals(longUri, "//1G1YZ23J9P5800001.veh.gm.com/core.usubscription/3/SubscriptionChange#Update")
- assertEquals(shortUri, "//1G1YZ23J9P5800001/0/3/32768")
- assertEquals(
- microUri.contentToString(),
- "[1, 3, -128, 0, 0, 0, 3, 0, 17, 49, 71, 49, 89, 90, 50, 51, 74, 57, 80, 53, 56, 48, 48, 48, 48, 49]"
- )
+ }
+ val serializedUri: String = uri.serialize()
+ assertEquals("//myAuthority/1/2/3", serializedUri)
+ }
+ @Test
+ @DisplayName("Test serializing a UUri with empty authority, ueId, ueVersionMajor and resourceId")
+ fun test_serializing_a_UUri_with_empty_authority_ueId_ueVersionMajor_and_resourceId() {
+ val uri = uUri {
+ authorityName = ""
+ ueId = 1
+ ueVersionMajor = 2
+ resourceId = 3
+ }
+ val serializedUri: String = uri.serialize()
+ assertEquals("/1/2/3", serializedUri)
+ }
+
+ @Test
+ @DisplayName("Test serializing a UUri with blank authority, ueId, ueVersionMajor and resourceId")
+ fun test_serializing_a_UUri_with_blank_authority_ueId_ueVersionMajor_and_resourceId() {
+ val uri = uUri {
+ authorityName = " "
+ ueId = 1
+ ueVersionMajor = 2
+ resourceId = 3
+ }
+ val serializedUri: String = uri.serialize()
+ assertEquals("/1/2/3", serializedUri)
}
}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/validator/UriValidatorTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uri/validator/UriValidatorTest.kt
index 518cef2..4c5f497 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/validator/UriValidatorTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/uri/validator/UriValidatorTest.kt
@@ -1,881 +1,144 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uri.validator
-import com.google.protobuf.ByteString
-import org.eclipse.uprotocol.uri.serializer.LongUriSerializer
import org.eclipse.uprotocol.v1.*
-import org.eclipse.uprotocol.validation.ValidationResult
-import org.json.JSONArray
-import org.json.JSONObject
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
-import java.io.BufferedReader
-import java.io.File
-import java.io.FileReader
-import java.io.IOException
-@Suppress("KotlinConstantConditions")
-internal class UriValidatorTest {
+class UriValidatorTest {
@Test
- @DisplayName("Test validate uri with no device name")
- fun test_validate_uri_with_no_entity_getName() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("//")
- val status: ValidationResult = uri.validate()
- assertTrue(uri.isEmpty())
- assertEquals("Uri is empty.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validate uri with uEntity")
- fun test_validate_uri_with_getEntity() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/hartley")
- val status: ValidationResult = uri.validate()
- assertEquals(ValidationResult.success(), status)
- }
-
- @Test
- @DisplayName("Test validate with malformed URI")
- fun test_validate_with_malformed_uri() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("hartley")
- val status: ValidationResult = uri.validate()
- assertTrue(uri.isEmpty())
- assertEquals("Uri is empty.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validate with blank UEntity Name")
- fun test_validate_with_blank_uentity_name_uri() {
- val status: ValidationResult = UUri.getDefaultInstance().validate()
- assertTrue(status.isFailure())
- assertEquals("Uri is empty.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validateRpcMethod with valid URI")
- fun test_validateRpcMethod_with_valid_uri() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/hartley//rpc.echo")
- val status: ValidationResult = uri.validateRpcMethod()
- assertEquals(ValidationResult.success(), status)
+ @DisplayName("Test isEmpty with default UUri")
+ fun test_isEmpty_with_default_UUri() {
+ assertTrue(UUri.getDefaultInstance().isEmpty())
}
@Test
- @DisplayName("Test validateRpcMethod with invalid URI")
- fun test_validateRpcMethod_with_invalid_uri() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/hartley/echo")
- val status: ValidationResult = uri.validateRpcMethod()
- assertTrue(status.isFailure())
- assertEquals("Uri is empty.", status.getMessage())
+ @DisplayName("Test isEmpty for non empty UUri")
+ fun test_isEmpty_for_non_empty_UUri() {
+ val uri = UUri.newBuilder()
+ .setAuthorityName("myAuthority")
+ .setUeId(0)
+ .setUeVersionMajor(1)
+ .setResourceId(1).build()
+ assertFalse(uri.isEmpty())
+ assertTrue(uri.isNotEmpty())
}
@Test
- @DisplayName("Test validateRpcMethod with malformed URI")
- fun test_validateRpcMethod_with_malformed_uri() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("hartley")
- val status: ValidationResult = uri.validateRpcMethod()
+ @DisplayName("Test isEmpty UUri for empty built UUri")
+ fun test_isEmpty_UUri_for_empty_built_UUri() {
+ val uri = UUri.newBuilder().build()
assertTrue(uri.isEmpty())
- assertEquals("Uri is empty.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validateRpcResponse with valid URI")
- fun test_validateRpcResponse_with_valid_uri() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/hartley//rpc.response")
- val status: ValidationResult = uri.validateRpcResponse()
- assertEquals(ValidationResult.success(), status)
- }
-
- @Test
- @DisplayName("Test validateRpcResponse with malformed URI")
- fun test_validateRpcResponse_with_malformed_uri() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("hartley")
- val status: ValidationResult = uri.validateRpcResponse()
- assertTrue(uri.isEmpty())
- assertEquals("Uri is empty.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validateRpcResponse with rpc type")
- fun test_validateRpcResponse_with_rpc_type() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/hartley//dummy.wrong")
- val status: ValidationResult = uri.validateRpcResponse()
- assertTrue(status.isFailure())
- assertEquals("Invalid RPC response type.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validateRpcResponse with invalid rpc response type")
- fun test_validateRpcResponse_with_invalid_rpc_response_type() {
- val uri: UUri = LongUriSerializer.INSTANCE.deserialize("/hartley//rpc.wrong")
- val status: ValidationResult = uri.validateRpcResponse()
- assertTrue(status.isFailure())
- assertEquals("Invalid RPC response type.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validate topic uri with version, when it is valid microRemote")
- fun test_topic_uri_with_version_when_it_is_valid_remote() {
- val uri = "//VCU.MY_CAR_VIN/body.access/1/door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate topic uri no version, when it is valid microRemote")
- fun test_topic_uri_no_version_when_it_is_valid_remote() {
- val uri = "//VCU.MY_CAR_VIN/body.access//door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate topic uri with version, when it is valid local")
- fun test_topic_uri_with_version_when_it_is_valid_local() {
- val uri = "/body.access/1/door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate topic uri no version, when it is valid local")
- fun test_topic_uri_no_version_when_it_is_valid_local() {
- val uri = "/body.access//door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate topic uri is invalid when uri contains nothing but schema")
- fun test_topic_uri_invalid_when_uri_has_schema_only() {
- val uri = ":"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate topic uri is invalid when uri contains empty use name local")
- fun test_topic_uri_invalid_when_uri_has_empty_use_name_local() {
- val uri = "/"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate topic uri is invalid when uri is microRemote but missing authority")
- fun test_topic_uri_invalid_when_uri_is_remote_no_authority() {
- val uri = "//"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate topic uri is invalid when uri is microRemote with use but missing authority")
- fun test_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() {
- val uri = "///body.access/1/door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate topic uri is invalid when uri has no use information")
- fun test_topic_uri_invalid_when_uri_is_missing_use_remote() {
- val uri = "//VCU.myvin///door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate microRemote topic uri is invalid when uri is missing use name")
- fun test_topic_uri_invalid_when_uri_is_missing_use_name_remote() {
- val uri = "/1/door.front_left#Door"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate local topic uri is invalid when uri is missing use name")
- fun test_topic_uri_invalid_when_uri_is_missing_use_name_local() {
- val uri = "//VCU.myvin//1"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validate()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc topic uri with version, when it is valid microRemote")
- fun test_rpc_topic_uri_with_version_when_it_is_valid_remote() {
- val uri = "//bo.cloud/petapp/1/rpc.response"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc topic uri no version, when it is valid microRemote")
- fun test_rpc_topic_uri_no_version_when_it_is_valid_remote() {
- val uri = "//bo.cloud/petapp//rpc.response"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc topic uri with version, when it is valid local")
- fun test_rpc_topic_uri_with_version_when_it_is_valid_local() {
- val uri = "/petapp/1/rpc.response"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc topic uri no version, when it is valid local")
- fun test_rpc_topic_uri_no_version_when_it_is_valid_local() {
- val uri = "/petapp//rpc.response"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc topic uri is invalid when uri contains nothing but schema")
- fun test_rpc_topic_uri_invalid_when_uri_has_schema_only() {
- val uri = ":"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc topic uri with version, when it is local but missing rpc.respons")
- fun test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_local() {
- val uri = "/petapp/1/dog"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
+ assertFalse(uri.isNotEmpty())
}
@Test
- @DisplayName("Test validate rpc topic uri with version, when it is microRemote but missing rpc.respons")
- fun test_rpc_topic_uri_with_version_when_it_is_not_valid_missing_rpc_response_remote() {
- val uri = "//petapp/1/dog"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
+ @DisplayName("Test isRpcMethod with default UUri")
+ fun test_isRpcMethod_with_default_UUri() {
+ assertFalse(UUri.getDefaultInstance().isRpcMethod())
}
@Test
- @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote but missing authority")
- fun test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority() {
- val uri = "//"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
+ @DisplayName("Test isRpcMethod with UUri having resourceId less than MIN_TOPIC_ID")
+ fun test_isRpcMethod_with_UUri_having_resourceId_less_than_MIN_TOPIC_ID() {
+ val uri = UUri.newBuilder()
+ .setResourceId(0x7FFF).build()
+ assertTrue(uri.isRpcMethod())
}
@Test
- @DisplayName("Test validate rpc topic uri is invalid when uri is microRemote with use but missing authority")
- fun test_rpc_topic_uri_invalid_when_uri_is_remote_no_authority_with_use() {
- val uri = "///body.access/1"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
+ @DisplayName("Test isRpcMethod with UUri having resourceId greater than MIN_TOPIC_ID")
+ fun test_isRpcMethod_with_UUri_having_resourceId_greater_than_MIN_TOPIC_ID() {
+ val uri = UUri.newBuilder()
+ .setResourceId(0x8000).build()
+ assertTrue(!uri.isRpcMethod())
}
@Test
- @DisplayName("Test validate rpc topic uri is invalid when uri has no use information")
- fun test_rpc_topic_uri_invalid_when_uri_is_missing_use() {
- val uri = "//VCU.myvin"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
+ @DisplayName("Test isRpcMethod with UUri having resourceId equal to MIN_TOPIC_ID")
+ fun test_isRpcMethod_with_UUri_having_resourceId_equal_to_MIN_TOPIC_ID() {
+ val uri = UUri.newBuilder()
+ .setResourceId(0x8000).build()
+ assertTrue(!uri.isRpcMethod())
}
@Test
- @DisplayName("Test validate microRemote rpc topic uri is invalid when uri is missing use name")
- fun test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_remote() {
- val uri = "/1"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
+ @DisplayName("Test isRpcResponse with default UUri")
+ fun test_isRpcResponse_with_default_UUri() {
+ assertTrue(!UUri.getDefaultInstance().isRpcResponse())
}
@Test
- @DisplayName("Test validate local rpc topic uri is invalid when uri is missing use name")
- fun test_rpc_topic_uri_invalid_when_uri_is_missing_use_name_local() {
- val uri = "//VCU.myvin//1"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri with version, when it is valid microRemote")
- fun test_rpc_method_uri_with_version_when_it_is_valid_remote() {
- val uri = "//VCU.myvin/body.access/1/rpc.UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri no version, when it is valid microRemote")
- fun test_rpc_method_uri_no_version_when_it_is_valid_remote() {
- val uri = "//VCU.myvin/body.access//rpc.UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri with version, when it is valid local")
- fun test_rpc_method_uri_with_version_when_it_is_valid_local() {
- val uri = "/body.access/1/rpc.UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri no version, when it is valid local")
- fun test_rpc_method_uri_no_version_when_it_is_valid_local() {
- val uri = "/body.access//rpc.UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri is invalid when uri contains nothing but schema")
- fun test_rpc_method_uri_invalid_when_uri_has_schema_only() {
- val uri = ":"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri with version, when it is local but not an rpc method")
- fun test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_local() {
- val uri = "/body.access//UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri with version, when it is microRemote but not an rpc method")
- fun test_rpc_method_uri_with_version_when_it_is_not_valid_not_rpc_method_remote() {
- val uri = "//body.access/1/UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri is invalid when uri is microRemote but missing authority")
- fun test_rpc_method_uri_invalid_when_uri_is_remote_no_authority() {
- val uri = "//"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri is invalid when uri is microRemote with use but missing authority")
- fun test_rpc_method_uri_invalid_when_uri_is_remote_no_authority_with_use() {
- val uri = "///body.access/1/rpc.UpdateDoor"
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uri)
- val status: ValidationResult = uuri.validateRpcMethod()
- assertEquals("", uuri.toString())
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri is invalid when uri has authority but missing remote case")
- fun test_rpc_method_uri_invalid_when_uri_is_remote_missing_authority_remotecase() {
- val uuri: UUri = uUri {
- entity = uEntity { name = "body.access" }
- resource = uResource {
- name = "rpc"
- instance = "UpdateDoor"
- }
- authority = uAuthority { }
- }
-
-
- val status: ValidationResult = uuri.validateRpcMethod()
- assertTrue(status.isFailure())
- assertEquals("Uri is remote missing uAuthority.", status.getMessage())
- }
-
- @Test
- @DisplayName("Test validate rpc method uri is invalid when uri has no use information")
- fun test_rpc_method_uri_invalid_when_uri_is_missing_use() {
- val uri = "//VCU.myvin"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate local rpc method uri is invalid when uri is missing use name")
- fun test_rpc_method_uri_invalid_when_uri_is_missing_use_name_local() {
- val uri = "/1/rpc.UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test validate microRemote rpc method uri is invalid when uri is missing use name")
- fun test_rpc_method_uri_invalid_when_uri_is_missing_use_name_remote() {
- val uri = "//VCU.myvin//1/rpc.UpdateDoor"
- val status: ValidationResult = LongUriSerializer.INSTANCE.deserialize(uri).validateRpcMethod()
- assertTrue(status.isFailure())
- }
-
- @Test
- @DisplayName("Test all valid uris from uris.json")
- @Throws(IOException::class)
- fun test_all_valid_uris() {
- // Access the "validUris" array
- val validUris: JSONArray = jsonObject.getJSONArray("validUris")
- for (i in 0 until validUris.length()) {
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(validUris.getString(i))
- val status: ValidationResult = uuri.validate()
- assertTrue(status.isSuccess())
- }
- }
-
- @Test
- @DisplayName("Test all invalid uris from uris.json")
- @Throws(IOException::class)
- fun test_all_invalid_uris() {
- // Access the "invalidUris" array
- val invalidUris: JSONArray = jsonObject.getJSONArray("invalidUris")
- for (i in 0 until invalidUris.length()) {
- val uriObject: JSONObject = invalidUris.getJSONObject(i)
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uriObject.getString("uri"))
- val status: ValidationResult = uuri.validate()
- assertTrue(status.isFailure())
- assertEquals(status.getMessage(), uriObject.getString("status_message"))
- }
- }
-
- @Test
- @DisplayName("Test all valid rpc uris from uris.json")
- @Throws(IOException::class)
- fun test_all_valid_rpc_uris() {
- // Access the "validRpcUris" array
- val validRpcUris: JSONArray = jsonObject.getJSONArray("validRpcUris")
- for (i in 0 until validRpcUris.length()) {
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(validRpcUris.getString(i))
- val status: ValidationResult = uuri.validateRpcMethod()
- assertTrue(status.isSuccess())
- }
- }
-
- @Test
- @DisplayName("Test all invalid rpc uris from uris.json")
- @Throws(IOException::class)
- fun test_all_invalid_rpc_uris() {
- // Access the "invalidRpcUris" array
- val invalidRpcUris: JSONArray = jsonObject.getJSONArray("invalidRpcUris")
- for (i in 0 until invalidRpcUris.length()) {
- val uriObject: JSONObject = invalidRpcUris.getJSONObject(i)
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(uriObject.getString("uri"))
- val status: ValidationResult = uuri.validateRpcMethod()
- assertTrue(status.isFailure())
- assertEquals(status.getMessage(), uriObject.getString("status_message"))
- }
- }
-
- @Test
- @DisplayName("Test all valid rpc response uris from uris.json")
- @Throws(IOException::class)
- fun test_all_valid_rpc_response_uris() {
- // Access the "validRpcResponseUris" array
- val validRpcResponseUris: JSONArray = jsonObject.getJSONArray("validRpcResponseUris")
- for (i in 0 until validRpcResponseUris.length()) {
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(validRpcResponseUris.getString(i))
- val status: ValidationResult = uuri.validateRpcResponse()
- assertTrue(uuri.isRpcResponse())
- assertTrue(status.isSuccess())
- }
- }
-
- @Test
- @DisplayName("Test valid rpc response uri")
- @Throws(IOException::class)
- fun test_valid_rpc_response_uri() {
- val uuri: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource {
- forRpcResponse()
- }
- }
-
- val status: ValidationResult = uuri.validateRpcResponse()
- assertTrue(uuri.isRpcResponse())
- assertTrue(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test invalid rpc method uri")
- fun test_invalid_rpc_method_uri() {
- val uuri = uUri {
- entity = uEntity {
- name = "hello.world"
- }
- resource = uResource {
- name = "testrpc"
- instance = "SayHello"
- }
- }
- val status: ValidationResult = uuri.validateRpcMethod()
- assertFalse(uuri.isRpcMethod())
- assertFalse(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test invalid rpc response uri")
- @Throws(IOException::class)
- fun test_invalid_rpc_response_uri() {
- val uuri1: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource {
- name = "rpc"
- id = 19999
- }
- }
- val status1 = uuri1.validateRpcResponse()
- assertFalse(uuri1.isRpcResponse())
- assertFalse(status1.isSuccess())
-
- val uuri2: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource {
- name = "testrpc"
- instance = "response"
- }
- }
- val status2 = uuri2.validateRpcResponse()
- assertFalse(uuri2.isRpcResponse())
- assertFalse(status2.isSuccess())
-
- val uuri3: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource {
- name = "rpc"
- instance = "testresponse"
- }
- }
- val status3 = uuri3.validateRpcResponse()
- assertFalse(uuri3.isRpcResponse())
- assertFalse(status3.isSuccess())
- }
-
- @Test
- @DisplayName("Test invalid rpc response uri")
- @Throws(IOException::class)
- fun test_another_invalid_rpc_response_uri() {
- val uuri: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource {
- name = "hello"
- id = 19999
- }
- }
-
- val status = uuri.validateRpcResponse()
- assertFalse(uuri.isRpcResponse())
- assertFalse(status.isSuccess())
- }
-
- @Test
- @DisplayName("Test all invalid rpc response uris from uris.json")
- @Throws(IOException::class)
- fun test_all_invalid_rpc_response_uris() {
- // Access the "invalidRpcResponseUris" array
- val invalidRpcResponseUris: JSONArray = jsonObject.getJSONArray("invalidRpcResponseUris")
- for (i in 0 until invalidRpcResponseUris.length()) {
- val uuri: UUri = LongUriSerializer.INSTANCE.deserialize(invalidRpcResponseUris.getString(i))
- val status: ValidationResult = uuri.validateRpcResponse()
- assertTrue(status.isFailure())
- }
- }
-
- @Test
- @DisplayName("Test is Remote is false for URI without UAuthority")
- fun test_is_remote_is_false_for_uri_without_uauthority() {
- val uri = uUri {
- authority = uAuthority { }
- entity = uEntity { name = "hartley" }
- resource = uResource {
- forRpcResponse()
- }
- }
- assertFalse(UAuthority.getDefaultInstance().isRemote())
- assertFalse(uri.authority.isRemote())
- }
-
- @Test
- @DisplayName("Test isRpcMethod with UResource and no UAuthority")
- fun test_is_rpc_method_with_uresource_and_no_uauthority() {
- assertFalse(uUri { }.isRpcMethod())
-
- val uri: UUri = uUri {
- entity = uEntity { name = "hartley" }
- resource = uResource { from(0x8000) }
- }
- assertFalse(uri.isRpcMethod())
- }
-
- @Test
- @DisplayName("Test isRpcMethod for UResource without an instance")
- fun test_is_rpc_method_for_uresource_without_an_instance() {
- val resource = uResource { name = "rpc" }
- assertFalse(resource.isRpcMethod())
- }
-
- @Test
- @DisplayName("Test isRpcMethod for UResource an empty instance")
- fun test_is_rpc_method_for_uresource_with_an_empty_instance() {
- val resource = uResource {
- name = "rpc"
- instance = ""
- }
- assertFalse(resource.isRpcMethod())
- }
-
- @Test
- @DisplayName("Test isRpcMethod for UResource with id that is less than min_topic")
- fun test_is_rpc_method_for_uresource_with_id_that_is_less_than_min_topic() {
- val resource = uResource {
- name = "rpc"
- id = 0
- }
- assertTrue(resource.isRpcMethod())
- }
-
- @Test
- @DisplayName("Test isRpcMethod for UResource with id that is greater than min_topic")
- fun test_is_rpc_method_for_uresource_with_id_that_is_greater_than_min_topic() {
- val resource = uResource {
- name = "rpc"
- id = 0x8000
- }
- assertFalse(resource.isRpcMethod())
- }
-
- @Test
- @DisplayName("Test isResolved when URI is long form only")
- fun test_is_resolved_when_uri_is_long_form_only() {
- val uri = uUri {
- entity = uEntity {
- name = "hartley"
- versionMajor = 23
- }
- resource = uResource {
- name = "rpc"
- instance = "echo"
- }
- }
- assertFalse(uri.isResolved())
- }
-
- @Test
- @DisplayName("Test isResolved when URI is micro form only")
- fun test_is_resolved_when_uri_is_micro_form_only() {
- val uri: UUri = uUri {
- entity = uEntity {
- id = 0
- versionMajor = 23
- }
- resource = uResource { from(0x8000) }
- }
- assertFalse(uri.isResolved())
- }
-
- @Test
- @DisplayName("Test isResolved when URI is both long and micro form")
- fun test_is_resolved_when_uri_is_both_long_and_micro_form() {
- val uri: UUri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- resource = uResource { forRpcResponse() }
- }
- assertTrue(uri.isResolved())
- }
-
- @Test
- @DisplayName("Test isRpcResponse when uri is a valid RPC response")
- fun test_is_rpc_response_when_uri_is_a_valid_rpc_response() {
- val uri: UUri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- resource = uResource { forRpcResponse() }
- }
+ @DisplayName("Test isRpcResponse with UUri having resourceId equal to 0")
+ fun test_isRpcResponse_with_UUri_having_resourceId_equal_to_0() {
+ val uri = UUri.newBuilder()
+ .setAuthorityName("hartley")
+ .setUeId(1)
+ .setUeVersionMajor(1)
+ .setResourceId(0).build()
assertTrue(uri.isRpcResponse())
}
@Test
- @DisplayName("Test isMicroForm when URI is empty")
- fun test_is_micro_form_when_uri_is_empty() {
- assertFalse(UUri.getDefaultInstance().isMicroForm())
- }
-
- @Test
- @DisplayName("Test isMicroForm when URI does not have UResource but does have UEntity")
- fun test_is_micro_form_when_uri_does_not_have_uresource_but_does_have_uentity() {
- val uri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- }
-
- assertFalse(uri.isMicroForm())
- }
-
- @Test
- @DisplayName("Test isLongForm when URI is null")
- fun test_is_long_form_when_uri_is_null() {
- assertFalse((null as UAuthority?).isLongForm())
- }
-
- @Test
- @DisplayName("Test isLongForm when UAuthority is not long form")
- fun test_is_long_form_when_uauthority_is_not_long_form() {
- val uri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- authority = UAuthority.getDefaultInstance()
- }
- assertFalse(uri.isLongForm())
- assertTrue(uri.authority.isLongForm())
+ @DisplayName("Test isRpcResponse with UUri having resourceId not equal to 0")
+ fun test_isRpcResponse_with_UUri_having_resourceId_not_equal_to_0() {
+ val uri = UUri.newBuilder()
+ .setAuthorityName("hartley")
+ .setUeId(1)
+ .setUeVersionMajor(1)
+ .setResourceId(1).build()
+ assertTrue(!uri.isRpcResponse())
}
@Test
- @DisplayName("Test isLongForm when UAuthority is long form but not the rest")
- fun test_is_long_form_when_uauthority_is_long_form_but_not_the_rest() {
- val uri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- authority = uAuthority { name = "vcu.veh.gm.com" }
- }
- assertFalse(uri.isLongForm())
- assertTrue(uri.authority.isLongForm())
+ @DisplayName("Test isRpcResponse with UUri having resourceId less than 0")
+ fun test_isRpcResponse_with_UUri_having_resourceId_less_than_0() {
+ val uri = UUri.newBuilder()
+ .setResourceId(-1).build()
+ assertTrue(!uri.isRpcResponse())
}
@Test
- @DisplayName("Test isLongForm when UAuthority blank name")
- fun test_is_long_form_when_uauthority_is_blank_name() {
- val uri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- authority = uAuthority { name = "" }
- }
- assertFalse(uri.isLongForm())
- assertFalse(uri.authority.isLongForm())
+ @DisplayName("Test isTopic with default UUri")
+ fun test_isTopic_with_default_UUri() {
+ assertFalse(UUri.getDefaultInstance().isTopic())
}
@Test
- @DisplayName("Test isLongForm when UAuthority is not long form but the rest is")
- fun test_is_long_form_when_uauthority_is_not_long_form_but_the_rest_is() {
- val uri = uUri {
- entity = uEntity {
- name = "hartley"
- id = 0
- versionMajor = 23
- }
- resource = uResource { forRpcResponse() }
- authority = uAuthority { id = ByteString.copyFromUtf8("hello Jello") }
- }
- assertFalse(uri.isLongForm())
- assertFalse(uri.authority.isLongForm())
+ @DisplayName("Test isTopic with UUri having resourceId greater than 0")
+ fun test_isTopic_with_UUri_having_resourceId_greater_than_0() {
+ val uri = UUri.newBuilder()
+ .setResourceId(1).build()
+ assertFalse(uri.isTopic())
}
@Test
- @DisplayName("Test isLocal when authority is null")
- fun test_is_local_when_authority_is_null() {
- assertFalse((null as UAuthority?).isLocal())
+ @DisplayName("Test isTopic with UUri having resourceId greater than 0x8000")
+ fun test_isTopic_with_UUri_having_resourceId_greater_than_0x8000() {
+ val uri = UUri.newBuilder()
+ .setResourceId(0x8001).build()
+ assertTrue(uri.isTopic())
}
@Test
- @DisplayName("Test isRemote when authority is null")
- fun test_is_remote_when_authority_is_null() {
- assertFalse((null as UAuthority?).isRemote())
- }
-
- @Test
- @DisplayName("Test isRemote when authority doesn't have a name but does have a number set")
- fun test_is_remote_when_authority_does_not_have_a_name_but_does_have_a_number_set() {
- val authority = uAuthority {
- id = ByteString.copyFromUtf8("hello Jello")
- }
- assertTrue(authority.isRemote())
- assertFalse(authority.hasName())
- assertEquals(authority.numberCase, UAuthority.NumberCase.ID)
- }
-
- @Test
- @DisplayName("Test isRemote when authority has name and number set")
- fun test_is_remote_when_authority_has_name_and_number_set() {
- val authority = uAuthority {
- name = "vcu.veh.gm.com"
- id = ByteString.copyFromUtf8("hello Jello")
- }
- assertTrue(authority.isRemote())
- assertTrue(authority.hasName())
- assertEquals(authority.numberCase, UAuthority.NumberCase.ID)
- }
-
- @Test
- @DisplayName("Test isRemote when authority has name and number is NOT set")
- fun test_is_remote_when_authority_has_name_and_number_is_not_set() {
- val authority = uAuthority {
- name = "vcu.veh.gm.com"
- }
- assertTrue(authority.isRemote())
- assertTrue(authority.hasName())
- assertEquals(authority.numberCase, UAuthority.NumberCase.NUMBER_NOT_SET)
+ @DisplayName("Test isRpcMethod should be false when resourceId is 0")
+ fun test_isRpcMethod_should_be_false_when_resourceId_is_0() {
+ val uri = UUri.newBuilder()
+ .setUeId(1)
+ .setResourceId(0).build()
+ assertFalse(uri.isRpcMethod())
}
-
- @get:Throws(IOException::class)
- private val jsonObject: JSONObject
- get() {
- val currentDirectory: String = System.getProperty("user.dir")
- val pkgname: String = this.javaClass.getPackage().name.replace(".", "/")
- val jsonFile = File(
- currentDirectory,
- ((("src" + File.separator) + "test" + File.separator) + "kotlin" + File.separator + pkgname + File.separator) + "uris.json"
- )
-
- // Open the file for reading
- val reader = BufferedReader(FileReader(jsonFile))
- // Read the JSON data as a string
- val jsonStringBuilder = StringBuilder()
- var line: String?
- while (reader.readLine().also { line = it } != null) {
- jsonStringBuilder.append(line)
- }
- reader.close()
- // Parse the JSON data into a JSONObject
- return JSONObject(jsonStringBuilder.toString())
- }
}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uri/validator/uris.json b/src/test/kotlin/org/eclipse/uprotocol/uri/validator/uris.json
deleted file mode 100644
index 2865428..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/uri/validator/uris.json
+++ /dev/null
@@ -1,107 +0,0 @@
-{
- "validUris": [
- "/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": "/",
- "status_message": "Uri is empty.",
- "reason": "Empty Uri"
- },
- {
- "uri": "//",
- "status_message": "Uri is empty.",
- "reason": "Empty Uri"
- },
- {
- "uri": "//vcu",
- "status_message": "Uri is missing uSoftware Entity name.",
- "reason": "Missing entity name."
- },
- {
- "uri": "//vcu.vin/",
- "status_message": "Uri is missing uSoftware Entity name.",
- "reason": "Missing entity name."
- },
- {
- "uri": "",
- "status_message": "Uri is empty.",
- "reason": "Empty Uri"
- },
- {
- "uri": ":",
- "status_message": "Uri is empty.",
- "reason": "Contains only schema"
- },
- {
- "uri": "///",
- "status_message": "Uri is empty.",
- "reason": "Empty Authority"
- },
- {
- "uri": "////",
- "status_message": "Uri is empty.",
- "reason": "Empty Uri"
- },
- {
- "uri": "1",
- "status_message": "Uri is empty.",
- "reason": "Invalid Uri, must begin with \"\/\""
- },
- {
- "uri": "a",
- "status_message": "Uri is empty.",
- "reason": "Invalid Uri, must begin with \"\/\""
- }
- ],
- "validRpcUris": [
- "/petapp/1/rpc.OpenWindow",
- "/petapp/1/rpc.response"
- ],
- "validRpcResponseUris": [
- "/petapp/1/rpc.response"
- ],
- "invalidRpcResponseUris": [
- "/petapp/1/rpc.OpenWindow"
- ],
- "invalidRpcUris": [
- {
- "uri": "/petapp//",
- "reason": "Missing uE version",
- "status_message": "Invalid RPC method uri. Uri should be the method to be called, or method from response."
- },
- {
- "uri": "/petapp",
- "reason": "Missing uE version",
- "status_message": "Invalid RPC method uri. Uri should be the method to be called, or method from response."
- },
- {
- "uri": "/petapp/1/",
- "reason": "Missing RPC Method Name",
- "status_message": "Invalid RPC method uri. Uri should be the method to be called, or method from response."
- },
- {
- "uri": "/petapp/1/rpc",
- "reason": "Missing RPC Method Name",
- "status_message": "Invalid RPC method uri. Uri should be the method to be called, or method from response."
- },
- {
- "uri": "/petapp/1/dummy",
- "reason": "Missing RPC Method Name",
- "status_message": "Invalid RPC method uri. Uri should be the method to be called, or method from response."
- },
- {
- "uri": "/petapp/1/rpc_dummy",
- "reason": "Missing RPC Method Name",
- "status_message": "Invalid RPC method uri. Uri should be the method to be called, or method from response."
- }
- ]
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UUIDFactoryTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UUIDFactoryTest.kt
index a3cf7b5..348bd00 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UUIDFactoryTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UUIDFactoryTest.kt
@@ -1,28 +1,20 @@
-/*
- * Copyright (c) 2023 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uuid.factory
-import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer
-import org.eclipse.uprotocol.uuid.serializer.MicroUuidSerializer
+import org.eclipse.uprotocol.uuid.serializer.deserializeAsUUID
+import org.eclipse.uprotocol.uuid.serializer.serialize
import org.eclipse.uprotocol.v1.UUID
import org.eclipse.uprotocol.v1.uUID
import org.junit.jupiter.api.Assertions.*
@@ -39,10 +31,9 @@ class UUIDFactoryTest {
fun test_uuidv8_creation() {
val now: Instant = Instant.now()
val uuid: UUID = UUIDV8(now)
- val version= uuid.getVersion()
+ val version = uuid.getVersion()
val time: Long? = uuid.getTime()
- val bytes = MicroUuidSerializer.INSTANCE.serialize(uuid)
- val uuidString = LongUuidSerializer.INSTANCE.serialize(uuid)
+ val uuidString = uuid.serialize()
assertNotNull(uuid)
assertTrue(uuid.isUProtocol())
@@ -51,14 +42,11 @@ class UUIDFactoryTest {
assertNotNull(version)
assertNotNull(time)
assertEquals(now.toEpochMilli(), time)
- assertTrue(bytes.isNotEmpty())
assertFalse(uuidString.isBlank())
- val uuid1: UUID = MicroUuidSerializer.INSTANCE.deserialize(bytes)
- val uuid2: UUID = LongUuidSerializer.INSTANCE.deserialize(uuidString)
+
+ val uuid1: UUID = uuidString.deserializeAsUUID()
assertFalse(uuid1 == UUID.getDefaultInstance())
- assertFalse(uuid2 == UUID.getDefaultInstance())
assertEquals(uuid, uuid1)
- assertEquals(uuid, uuid2)
}
@Test
@@ -91,8 +79,7 @@ class UUIDFactoryTest {
val uuid: UUID = UUIDV6(now)
val version = uuid.getVersion()
val time: Long? = uuid.getTime()
- val bytes = MicroUuidSerializer.INSTANCE.serialize(uuid)
- val uuidString = LongUuidSerializer.INSTANCE.serialize(uuid)
+ val uuidString = uuid.serialize()
assertNotNull(uuid)
assertTrue(uuid.isUuidv6())
assertTrue(uuid.isUuid())
@@ -100,13 +87,10 @@ class UUIDFactoryTest {
assertNotNull(version)
assertNotNull(time)
assertEquals(now.toEpochMilli(), time)
- assertTrue(bytes.isNotEmpty())
+
assertFalse(uuidString.isBlank())
- val uuid1: UUID = MicroUuidSerializer.INSTANCE.deserialize(bytes)
- val uuid2: UUID = LongUuidSerializer.INSTANCE.deserialize(uuidString)
- assertFalse(uuid1 == UUID.getDefaultInstance())
+ val uuid2: UUID = uuidString.deserializeAsUUID()
assertFalse(uuid2 == UUID.getDefaultInstance())
- assertEquals(uuid, uuid1)
assertEquals(uuid, uuid2)
}
@@ -120,23 +104,18 @@ class UUIDFactoryTest {
}
val version = uuid.getVersion()
val time: Long? = uuid.getTime()
- val bytes = MicroUuidSerializer.INSTANCE.serialize(uuid)
- val uuidString = LongUuidSerializer.INSTANCE.serialize(uuid)
+ val uuidString = uuid.serialize()
assertNotNull(uuid)
assertFalse(uuid.isUuidv6())
assertFalse(uuid.isUProtocol())
assertFalse(uuid.isUuid())
assertNotNull(version)
assertNull(time)
- assertTrue(bytes.isNotEmpty())
- assertFalse(uuidString.isBlank())
- val uuid1: UUID = MicroUuidSerializer.INSTANCE.deserialize(bytes)
- val uuid2: UUID = LongUuidSerializer.INSTANCE.deserialize(uuidString)
+ assertFalse(uuidString.isBlank())
- assertFalse(uuid1 == UUID.getDefaultInstance())
+ val uuid2: UUID = uuidString.deserializeAsUUID()
assertFalse(uuid2 == UUID.getDefaultInstance())
- assertEquals(uuid, uuid1)
assertEquals(uuid, uuid2)
}
@@ -149,32 +128,20 @@ class UUIDFactoryTest {
}
val version = uuid.getVersion()
val time: Long? = uuid.getTime()
- val bytes = MicroUuidSerializer.INSTANCE.serialize(uuid)
- val uuidString = LongUuidSerializer.INSTANCE.serialize(uuid)
+ val uuidString = uuid.serialize()
assertNotNull(uuid)
assertFalse(uuid.isUuidv6())
assertFalse(uuid.isUProtocol())
assertNotNull(version)
assertEquals(UUIDVersion.VERSION_UNKNOWN, version)
assertNull(time)
- assertTrue(bytes.isNotEmpty())
assertFalse(uuidString.isBlank())
- val uuid1: UUID = MicroUuidSerializer.INSTANCE.deserialize(bytes)
- assertTrue(uuid1 == UUID.getDefaultInstance())
- assertEquals(uuid, uuid1)
- val uuid2: UUID = LongUuidSerializer.INSTANCE.deserialize(uuidString)
+ val uuid2: UUID = uuidString.deserializeAsUUID()
assertTrue(uuid2 == UUID.getDefaultInstance())
assertEquals(uuid, uuid2)
}
- @Test
- @DisplayName("Test UuidUtils for a null UUID")
- fun test_uuidutils_for_null_uuid() {
- assertTrue(MicroUuidSerializer.INSTANCE.serialize(null).isEmpty())
- assertTrue(LongUuidSerializer.INSTANCE.serialize(null).isBlank())
- }
-
@Test
@DisplayName("Test UuidUtils fromString an invalid built UUID")
fun test_uuidutils_from_invalid_uuid() {
@@ -184,8 +151,7 @@ class UUIDFactoryTest {
} // Invalid UUID type
assertEquals(UUIDVersion.VERSION_UNKNOWN, uuid.getVersion())
assertNull(uuid.getTime())
- assertTrue(MicroUuidSerializer.INSTANCE.serialize(uuid).isNotEmpty())
- assertFalse(LongUuidSerializer.INSTANCE.serialize(uuid).isBlank())
+ assertFalse(uuid.serialize().isBlank())
assertFalse(uuid.isUuidv6())
assertFalse(uuid.isUProtocol())
assertFalse(uuid.isUuid())
@@ -193,19 +159,8 @@ class UUIDFactoryTest {
@Test
@DisplayName("Test UuidUtils fromString with invalid string")
- fun test_uuidutils_fromstring_with_invalid_string() {
- val uuid: UUID = LongUuidSerializer.INSTANCE.deserialize(null)
- assertTrue(uuid == UUID.getDefaultInstance())
- val uuid1: UUID = LongUuidSerializer.INSTANCE.deserialize("")
- assertTrue(uuid1 == UUID.getDefaultInstance())
- }
-
- @Test
- @DisplayName("Test UuidUtils fromBytes with invalid bytes")
- fun test_uuidutils_frombytes_with_invalid_bytes() {
- val uuid: UUID = MicroUuidSerializer.INSTANCE.deserialize(null)
- assertTrue(uuid == UUID.getDefaultInstance())
- val uuid1: UUID = MicroUuidSerializer.INSTANCE.deserialize(ByteArray(0))
+ fun test_uuidutils_from_string_with_invalid_string() {
+ val uuid1: UUID = "".deserializeAsUUID()
assertTrue(uuid1 == UUID.getDefaultInstance())
}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.kt
index 178d54b..21054a5 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.kt
@@ -1,51 +1,32 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * SPDX-FileType: SOURCE
- * SPDX-FileCopyrightText: 2024 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
+
package org.eclipse.uprotocol.uuid.factory
import org.eclipse.uprotocol.v1.*
import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
+import java.time.Instant
import kotlin.math.abs
import kotlin.test.assertNull
class UuidUtilsTest {
-
- private val testSource = uUri {
- entity = uEntity { name = "body.access" }
- resource = uResource {
- name = "door"
- instance = "front_left"
- message = "Door"
- }
- }
-
@Test
@Throws(InterruptedException::class)
fun testGetElapsedTime() {
val testID = createId()
Thread.sleep(DELAY_MS.toLong())
- //assertEquals(DELAY_MS, testID.getElapsedTime()?.toInt(), DELTA)
assertEquals(DELAY_MS, testID.getElapsedTime()?.toInt(), DELTA)
}
@@ -82,37 +63,6 @@ class UuidUtilsTest {
assertNull(id.getRemainingTime(DELAY_MS - DELTA))
}
- @Test
- @Throws(InterruptedException::class)
- fun testGetRemainingTimeAttributes() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = TTL
- }
- assertEquals(TTL, attributes.getRemainingTime()?.toInt(), DELTA)
- Thread.sleep(DELAY_MS.toLong())
- assertEquals(TTL - DELAY_MS, attributes.getRemainingTime()?.toInt(), DELTA)
- }
-
- @Test
- fun testGetRemainingTimeAttributesNoTtl() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- }
- assertNull(attributes.getRemainingTime())
- }
-
- @Test
- @Throws(InterruptedException::class)
- fun testGetRemainingTimeAttributesExpired() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = DELAY_MS - DELTA
- }
- Thread.sleep(DELAY_MS.toLong())
- assertNull(attributes.getRemainingTime())
- }
-
@Test
@Throws(InterruptedException::class)
fun testIsExpired() {
@@ -130,23 +80,11 @@ class UuidUtilsTest {
}
@Test
- @Throws(InterruptedException::class)
- fun testIsExpiredAttributes() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- ttl = DELAY_MS - DELTA
- }
- assertFalse(attributes.isExpired())
- Thread.sleep(DELAY_MS.toLong())
- assertTrue(attributes.isExpired())
- }
-
- @Test
- fun testIsExpiredAttributesNoTtl() {
- val attributes: UAttributes = uAttributes {
- forPublication(testSource, UPriority.UPRIORITY_CS0)
- }
- assertFalse(attributes.isExpired())
+ @DisplayName("Test getElapseTime() when UUID time is in the future")
+ fun testGetElapsedTimePast() {
+ val now = Instant.now().plusMillis(DELAY_MS.toLong())
+ val id: UUID = UUIDV8(now)
+ assertNull(id.getElapsedTime())
}
private fun assertEquals(expect: Int, actual: Int?, delta: Int?) {
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializerKtTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializerKtTest.kt
new file mode 100644
index 0000000..5101940
--- /dev/null
+++ b/src/test/kotlin/org/eclipse/uprotocol/uuid/serializer/UuidSerializerKtTest.kt
@@ -0,0 +1,45 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.uuid.serializer
+
+import org.eclipse.uprotocol.v1.UUID
+import org.eclipse.uprotocol.v1.uUID
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+
+class UuidSerializerTest {
+ @Test
+ @DisplayName("Test serializer with good uuid")
+ fun test_serializer_with_good_uuid() {
+ val uuidStr = "123e4567-e89b-12d3-a456-426614174000"
+ val uuid: UUID = uuidStr.deserializeAsUUID()
+ assertEquals(uuidStr, uuid.serialize())
+ }
+
+ @Test
+ @DisplayName("Test serializer with empty uuid")
+ fun test_serializer_with_empty_uuid() {
+ val uuid = uUID { }
+ assertEquals("00000000-0000-0000-0000-000000000000", uuid.serialize())
+ }
+
+ @Test
+ @DisplayName("Test deserializer with invalid uuid")
+ fun test_deserializer_with_invalid_uuid() {
+ val uuidStr = "sdsadfasdfsfgagASDfadasfgsdfgs"
+ val uuid: UUID = uuidStr.deserializeAsUUID()
+ assertEquals(uUID { }, uuid)
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.kt b/src/test/kotlin/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.kt
index 0f0f2f9..0df982a 100644
--- a/src/test/kotlin/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.kt
+++ b/src/test/kotlin/org/eclipse/uprotocol/uuid/validator/UuidValidatorTest.kt
@@ -1,30 +1,23 @@
-/*
- * Copyright (c) 2023 General Motors GTO LLC
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
- * 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
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
+
package org.eclipse.uprotocol.uuid.validator
import org.eclipse.uprotocol.uuid.factory.UUIDV6
import org.eclipse.uprotocol.uuid.factory.UUIDV8
import org.eclipse.uprotocol.uuid.factory.isUuidv6
-import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer
+import org.eclipse.uprotocol.uuid.serializer.deserializeAsUUID
import org.eclipse.uprotocol.uuid.validate.UUIDv6Validator
import org.eclipse.uprotocol.uuid.validate.UUIDv8Validator
import org.eclipse.uprotocol.uuid.validate.UuidValidator
@@ -115,7 +108,7 @@ class UuidValidatorTest {
@Test
@DisplayName("Test UUIDv6 with bad variant")
fun test_uuidv6_with_bad_variant() {
- val uuid: UUID = LongUuidSerializer.INSTANCE.deserialize("1ee57e66-d33a-65e0-4a77-3c3f061c1e9e")
+ val uuid: UUID = "1ee57e66-d33a-65e0-4a77-3c3f061c1e9e".deserializeAsUUID()
assertFalse(uuid == UUID.getDefaultInstance())
val validator: UuidValidator = UuidValidator.getValidator(uuid)
assertNotNull(validator)
diff --git a/src/test/kotlin/org/eclipse/uprotocol/v1/UPayloadKtExtTest.kt b/src/test/kotlin/org/eclipse/uprotocol/v1/UPayloadKtExtTest.kt
deleted file mode 100644
index 2ba2ed1..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/v1/UPayloadKtExtTest.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.eclipse.uprotocol.v1
-
-import com.google.protobuf.Any
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotNull
-import org.junit.jupiter.api.Test
-
-
-class UPayloadKtExtTest {
- @Test
- fun testPackToAny() {
- val uStatus = uStatus { }
- val uPayload = uPayload {
- packToAny(uStatus)
- }
- assertNotNull(uPayload)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY, uPayload.format)
- assertEquals(
- Any.pack(uStatus).toByteString(),
- uPayload.value
- )
- }
-
- @Test
- fun testPack() {
- val uStatus = uStatus { }
- val uPayload = uPayload {
- pack(uStatus)
- }
- assertNotNull(uPayload)
- assertEquals(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF, uPayload.format)
- assertEquals(uStatus.toByteString(), uPayload.value)
- }
-}
diff --git a/src/test/kotlin/org/eclipse/uprotocol/v1/UResourceKtExtTest.kt b/src/test/kotlin/org/eclipse/uprotocol/v1/UResourceKtExtTest.kt
deleted file mode 100644
index 14ed0fd..0000000
--- a/src/test/kotlin/org/eclipse/uprotocol/v1/UResourceKtExtTest.kt
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2024 General Motors GTO LLC
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.eclipse.uprotocol.v1
-
-import org.eclipse.uprotocol.uServiceTopic
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-
-class UResourceFactoryTest {
- @Test
- fun test_forRpcResponse() {
- val resource = uResource {
- forRpcResponse()
- }
- assertEquals("rpc", resource.name)
- assertEquals("response", resource.instance)
- assertEquals(0, resource.id)
- }
-
- @Test
- fun test_forRpcRequest_without_argu() {
- val resource = uResource {
- forRpcRequest()
- }
- assertEquals("rpc", resource.name)
- assertEquals("", resource.instance)
- assertEquals(0, resource.id)
- }
-
- @Test
- fun test_forRpcRequest_with_method() {
- val resource = uResource {
- forRpcRequest("test")
- }
- assertEquals("rpc", resource.name)
- assertEquals("test", resource.instance)
- assertEquals(0, resource.id)
- }
-
- @Test
- fun test_forRpcRequest_with_id() {
- val resource = uResource {
- forRpcRequest(id = 999)
- }
- assertEquals("rpc", resource.name)
- assertEquals("", resource.instance)
- assertEquals(999, resource.id)
- }
-
- @Test
- fun test_forRpcRequest() {
- val resource = uResource {
- forRpcRequest(method = "test", id = 999)
- }
- assertEquals("rpc", resource.name)
- assertEquals("test", resource.instance)
- assertEquals(999, resource.id)
- }
-
- @Test
- fun test_fromId_valid_id() {
- val idTest = Random.nextInt(0, 999)
- val resource = uResource {
- from(idTest)
- }
- assertEquals("rpc", resource.name)
- assertEquals("", resource.instance)
- assertEquals(idTest, resource.id)
- }
-
- @Test
- fun test_fromId_invalid_id() {
- val idTest = Random.nextInt(1000, Int.MAX_VALUE)
- val resource = uResource {
- from(idTest)
- }
- assertEquals("", resource.name)
- assertEquals("", resource.instance)
- assertEquals(idTest, resource.id)
- }
-
- @Test
- fun test_from_uservice_topic_valid_service_topic() {
- val topic = uServiceTopic {
- name = "SubscriptionChange"
- id = 0
- message = "Update"
- }
- val resource: UResource = uResource {
- from(topic)
- }
- assertEquals(resource.name, "SubscriptionChange")
- assertEquals(resource.instance, "")
- assertEquals(resource.id, 0)
- assertEquals(resource.message, "Update")
- }
-
- @Test
- fun test_from_uservice_topic_valid_service_topic_with_instance() {
- val topic = uServiceTopic {
- name = "door.front_left"
- id = 0x8000
- message = "Door"
- }
-
- val resource: UResource = uResource {
- from(topic)
- }
- assertEquals(resource.name, "door")
- assertEquals(resource.instance, "front_left")
- assertEquals(resource.id, 0x8000)
- assertEquals(resource.message, "Door")
- }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/org/eclipse/uprotocol/validation/ValidationResultTest.kt b/src/test/kotlin/org/eclipse/uprotocol/validation/ValidationResultTest.kt
new file mode 100644
index 0000000..4931414
--- /dev/null
+++ b/src/test/kotlin/org/eclipse/uprotocol/validation/ValidationResultTest.kt
@@ -0,0 +1,43 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.eclipse.uprotocol.validation
+
+import org.eclipse.uprotocol.v1.UCode
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+
+class ValidationResultTest {
+ @Test
+ @DisplayName("Test creating a successful ValidationResult")
+ fun testCreateSuccess() {
+ val result = ValidationResult.success()
+ Assertions.assertTrue(result.isSuccess())
+ Assertions.assertFalse(result.isFailure())
+ Assertions.assertEquals("", result.getMessage())
+ Assertions.assertEquals(result.toStatus().code, UCode.OK)
+ Assertions.assertEquals(result.toString(), "ValidationResult.Success()")
+ }
+
+ @Test
+ @DisplayName("Test creating a failed ValidationResult")
+ fun testCreateFailure() {
+ val result = ValidationResult.failure("Failed")
+ Assertions.assertFalse(result.isSuccess())
+ Assertions.assertTrue(result.isFailure())
+ Assertions.assertEquals("Failed", result.getMessage())
+ Assertions.assertEquals(result.toStatus().code, UCode.INVALID_ARGUMENT)
+ Assertions.assertEquals(result.toString(), "ValidationResult.Failure(message='Failed')")
+ }
+}
\ No newline at end of file