Skip to content

Commit

Permalink
Merge pull request #21 from dddj698/kotlin_dsl
Browse files Browse the repository at this point in the history
Use Kotlin DSL for builder functions
  • Loading branch information
Steven Hartley authored Mar 13, 2024
2 parents 527d94a + 0ed2e52 commit c9bc5f7
Show file tree
Hide file tree
Showing 27 changed files with 1,078 additions and 914 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import java.util.*
* 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.
*/
class UCloudEventAttributes private constructor(
data class UCloudEventAttributes internal constructor(
private val hash: String? = null,
private val priority: UPriority? = null,
private val ttl: Int? = null,
Expand Down Expand Up @@ -101,111 +101,51 @@ class UCloudEventAttributes private constructor(
/**
* Builder for constructing the UCloudEventAttributes.
*/
class UCloudEventAttributesBuilder {
var hash: String? = null
var priority: UPriority? = null
var ttl: Int? = null
var token: String? = null
var traceparent: String? = null

class UCloudEventAttributesBuilder @PublishedApi internal constructor() {
/**
* add an HMAC generated on the data portion of the CloudEvent message using the device key.
* @param hash an HMAC generated on the data portion of the CloudEvent message using the device key.
* @return Returns the UCloudEventAttributesBuilder with the configured hash.
*/
fun withHash(hash: String?): UCloudEventAttributesBuilder {
this.hash = hash
return this
}
var hash: String? = null

/**
* add a uProtocol Prioritization classifications.
* @param priority uProtocol Prioritization classifications.
* @return Returns the UCloudEventAttributesBuilder with the configured priority.
*/
fun withPriority(priority: UPriority?): UCloudEventAttributesBuilder {
this.priority = priority
return this
}
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.
* @param ttl How long this event should live for after it was generated (in milliseconds).
* Events without this attribute (or value is 0) MUST NOT timeout.
* @return Returns the UCloudEventAttributesBuilder with the configured time to live.
*/
fun withTtl(ttl: Int?): UCloudEventAttributesBuilder {
this.ttl = ttl
return this
}
var ttl: Int? = null

/**
* Add an Oauth2 access token to perform the access request defined in the request message.
* @param token An Oauth2 access token to perform the access request defined in the request message.
* @return Returns the UCloudEventAttributesBuilder with the configured OAuth token.
*/
fun withToken(token: String?): UCloudEventAttributesBuilder {
this.token = token
return this
}
var token: String? = null

/**
* Add an identifier used to correlate observability across related events.
* @param traceparent An identifier used to correlate observability across related events.
* @return Returns the UCloudEventAttributesBuilder with the configured traceparent.
*/
fun withTraceparent(traceparent: String?): UCloudEventAttributesBuilder {
this.traceparent = traceparent
return this
}
var traceparent: String? = null


/**
* Construct the UCloudEventAttributes from the builder.
* @return Returns a constructed UProperty.
*/
fun build(): UCloudEventAttributes {
@JvmSynthetic
@PublishedApi
internal fun build(): UCloudEventAttributes {
// validation if needed
return UCloudEventAttributes(this)
}
}


override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass !== other.javaClass) return false
val that = other as UCloudEventAttributes
return Objects.equals(hash, that.hash) && priority == that.priority && Objects.equals(
ttl,
that.ttl
) && Objects.equals(token, that.token) && Objects.equals(traceparent, that.traceparent)
}

override fun hashCode(): Int {
return Objects.hash(hash, priority, ttl, token, traceparent)
}

override fun toString(): String {
val traceParentString = traceparent?.let { ", traceparent='$it'" }?:""
return "UCloudEventAttributes{" +
"hash='" + hash + '\'' +
", priority=" + priority +
", ttl=" + ttl +
", token='" + token + '\'' +
traceParentString +
'}'
}

companion object {
private val EMPTY = UCloudEventAttributes(null, null, null, null)
val EMPTY = UCloudEventAttributes()

/**
* Static factory method for creating an empty cloud event attributes object, to avoid working with null<br></br>
* @return Returns an empty cloud event attributes that indicates
* that there are no added additional attributes to configure.
*/
fun empty(): UCloudEventAttributes {
return EMPTY
}
@JvmName("-initializeUCloudEventAttributes")
inline fun uCloudEventAttributes(block: UCloudEventAttributesBuilder.() -> Unit) =
UCloudEventAttributesBuilder().apply(block).build()
}
}
106 changes: 29 additions & 77 deletions src/main/kotlin/org/eclipse/uprotocol/rpc/CallOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,114 +24,66 @@

package org.eclipse.uprotocol.rpc

import java.util.Objects
import java.util.Optional

/**
* This class is used when making uRPC calls to pass additional options. Copied from Misha's class.
* @property timeout a timeout in milliseconds
* @property token An optional OAuth2 access token
*/
class CallOptions private constructor(private val mTimeout: Int, token: String?) {
private val mToken: String

private constructor(builder: Builder) : this(builder.mTimeout, builder.mToken)

init {
mToken = token ?: ""
}

/**
* Get a timeout.
*
* @return A timeout in milliseconds.
*/
fun timeout(): Int {
return mTimeout
}

/**
* Get an OAuth2 access token.
*
* @return An Optional OAuth2 access token.
*/
fun token(): Optional<String> {
return if (mToken.isBlank()) Optional.empty() else Optional.of(mToken)
}
data class CallOptions internal constructor(
val timeout: Int = TIMEOUT_DEFAULT,
val token: String = TOKEN_DEFAULT
) {
private constructor(builder: Builder) : this(builder.timeout, builder.token)

/**
* Builder for constructing `CallOptions`.
* @property timeout a timeout in milliseconds
* @property token an OAuth2 access token
*/
class Builder {
var mTimeout = TIMEOUT_DEFAULT
var mToken = ""

/**
* Add a timeout.
*
* @param timeout A timeout in milliseconds.
* @return This builder.
*/
fun withTimeout(timeout: Int): Builder {
mTimeout = if (timeout <= 0) TIMEOUT_DEFAULT else timeout
return this
}

/**
* Add an OAuth2 access token.
*
* @param token An OAuth2 access token.
* @return This builder.
*/
fun withToken(token: String): Builder {
mToken = token
return this
}
class Builder @PublishedApi internal constructor() {
var timeout = TIMEOUT_DEFAULT
set(value) {
field = value.takeIf { it >= 0 } ?: TIMEOUT_DEFAULT
}
var token = TOKEN_DEFAULT
set(value) {
field = value.ifBlank { TOKEN_DEFAULT }
}

/**
* Construct a `CallOptions` from this builder.
*
* @return A constructed `CallOptions`.
*/
fun build(): CallOptions {
@JvmSynthetic
@PublishedApi
internal fun build(): CallOptions {
return CallOptions(this)
}
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass !== other.javaClass) return false
val that = other as CallOptions
return mTimeout == that.mTimeout && Objects.equals(mToken, that.mToken)
}

override fun hashCode(): Int {
return Objects.hash(mTimeout, mToken)
}

override fun toString(): String {
return "CallOptions{" +
"mTimeout=" + mTimeout +
", mToken='" + mToken + '\'' +
'}'
}

companion object {
/**
* Default timeout of a call in milliseconds.
*/
const val TIMEOUT_DEFAULT = 10000

/**
* Default token.
*/
const val TOKEN_DEFAULT = ""

/**
* Default instance.
*/
val DEFAULT = CallOptions(TIMEOUT_DEFAULT, "")
val DEFAULT = CallOptions(TIMEOUT_DEFAULT, TOKEN_DEFAULT)

/**
* Constructs a new builder.
*
* @return A builder.
*/
fun newBuilder(): Builder {
return Builder()
}
@JvmName("-initializeCallOptions")
inline fun callOptions(block: Builder.() -> Unit) = Builder().apply(block).build()
}
}
69 changes: 69 additions & 0 deletions src/main/kotlin/org/eclipse/uprotocol/transport/UPayloadExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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 <T : Message> unpack(payload: UPayload, clazz: Class<T>): T? {
return try {
when (payload.format) {
UPayloadFormat.UNRECOGNIZED, 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 <reified T : Message> UPayload.unpack(): T? {
return unpack(this, T::class.java)
}

Loading

0 comments on commit c9bc5f7

Please sign in to comment.