diff --git a/client/src/main/kotlin/org/imdc/extensions/client/ClientHook.kt b/client/src/main/kotlin/org/imdc/extensions/client/ClientHook.kt index 9d888fd..03b8652 100644 --- a/client/src/main/kotlin/org/imdc/extensions/client/ClientHook.kt +++ b/client/src/main/kotlin/org/imdc/extensions/client/ClientHook.kt @@ -13,6 +13,7 @@ import org.imdc.extensions.common.UtilitiesExtensions import org.imdc.extensions.common.addPropertyBundle import org.imdc.extensions.common.expressions.IsAvailableFunction import org.imdc.extensions.common.expressions.LogicalPredicate.Companion.registerLogicFunctions +import org.imdc.extensions.common.expressions.UUID4Function @Suppress("unused") class ClientHook : AbstractClientModuleHook() { @@ -50,6 +51,11 @@ class ClientHook : AbstractClientModuleHook() { IsAvailableFunction(), ) registerLogicFunctions() + addFunction( + UUID4Function.NAME, + UUID4Function.CATEGORY, + UUID4Function(), + ) } } } diff --git a/common/src/main/java/org/imdc/extensions/common/UtilitiesExtensions.java b/common/src/main/java/org/imdc/extensions/common/UtilitiesExtensions.java index 3273e84..c6b66e6 100644 --- a/common/src/main/java/org/imdc/extensions/common/UtilitiesExtensions.java +++ b/common/src/main/java/org/imdc/extensions/common/UtilitiesExtensions.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -129,4 +130,9 @@ public FunctionFactory getFunctionFactory() { return context.getExpressionFunctionFactory(); } } + + @ScriptFunction(docBundlePrefix = "UtilitiesExtensions") + public UUID getUUID4() { + return UUID.randomUUID(); + } } diff --git a/common/src/main/kotlin/org/imdc/extensions/common/expressions/UUID4Function.kt b/common/src/main/kotlin/org/imdc/extensions/common/expressions/UUID4Function.kt new file mode 100644 index 0000000..969de96 --- /dev/null +++ b/common/src/main/kotlin/org/imdc/extensions/common/expressions/UUID4Function.kt @@ -0,0 +1,23 @@ +package org.imdc.extensions.common.expressions + +import com.inductiveautomation.ignition.common.expressions.Expression +import com.inductiveautomation.ignition.common.expressions.functions.AbstractFunction +import com.inductiveautomation.ignition.common.model.values.BasicQualifiedValue +import com.inductiveautomation.ignition.common.model.values.QualifiedValue +import java.util.UUID + +class UUID4Function : AbstractFunction() { + override fun validateNumArgs(num: Int): Boolean = num == 0 + override fun execute(expressions: Array): QualifiedValue { + return BasicQualifiedValue(UUID.randomUUID()) + } + + override fun getArgDocString(): String = "" + override fun getFunctionDisplayName(): String = NAME + override fun getType(): Class<*> = UUID::class.java + + companion object { + const val NAME = "uuid4" + const val CATEGORY = "Advanced" + } +} diff --git a/common/src/main/resources/org/imdc/extensions/common/UtilitiesExtensions.properties b/common/src/main/resources/org/imdc/extensions/common/UtilitiesExtensions.properties index c5ce55e..cbc97f7 100644 --- a/common/src/main/resources/org/imdc/extensions/common/UtilitiesExtensions.properties +++ b/common/src/main/resources/org/imdc/extensions/common/UtilitiesExtensions.properties @@ -8,3 +8,7 @@ deepCopy.returns=A plain Python primitive object. evalExpression.desc=Evaluates the supplied expression. Provide keyword arguments to populate values to curly braces. evalExpression.param.expression=The expression to evaluate. evalExpression.returns=A QualifiedValue with the result of the provided expression. + +getUUID4.desc=Returns type 4 pseudo randomly generated UUID. +getUUID4.returns=A type 4 pseudo randomly generated UUID. + diff --git a/common/src/test/kotlin/org/imdc/extensions/common/UUID4Tests.kt b/common/src/test/kotlin/org/imdc/extensions/common/UUID4Tests.kt new file mode 100644 index 0000000..2c71256 --- /dev/null +++ b/common/src/test/kotlin/org/imdc/extensions/common/UUID4Tests.kt @@ -0,0 +1,24 @@ +package org.imdc.extensions.common + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.beInstanceOf +import org.imdc.extensions.common.ExpressionTestHarness.Companion.withFunction +import org.imdc.extensions.common.expressions.UUID4Function +import java.util.* + +class UUID4Tests : FunSpec() { + init { + context("RandomUUID") { + withFunction("uuid4", UUID4Function()) { + test("Instance of UUID") { + evaluate("uuid4()") should beInstanceOf() + } + test("Unique results") { + evaluate("uuid4() = uuid4()") shouldBe false + } + } + } + } +} diff --git a/common/src/test/kotlin/org/imdc/extensions/common/UtilitiesExtensionsTests.kt b/common/src/test/kotlin/org/imdc/extensions/common/UtilitiesExtensionsTests.kt index a853fdd..ede9bfc 100644 --- a/common/src/test/kotlin/org/imdc/extensions/common/UtilitiesExtensionsTests.kt +++ b/common/src/test/kotlin/org/imdc/extensions/common/UtilitiesExtensionsTests.kt @@ -1,11 +1,14 @@ package org.imdc.extensions.common import io.kotest.matchers.nulls.shouldBeNull +import io.kotest.matchers.should import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.beInstanceOf import io.mockk.mockk import org.python.core.Py import org.python.core.PyDictionary import org.python.core.PyList +import java.util.UUID @Suppress("PyUnresolvedReferences", "PyInterpreter") class UtilitiesExtensionsTests : JythonTest( @@ -46,5 +49,13 @@ class UtilitiesExtensionsTests : JythonTest( } } } + context("UUID4 tests") { + test("Instance of UUID") { + eval("utils.getUUID4()") should beInstanceOf() + } + test("Unique results") { + eval("utils.getUUID4() == utils.getUUID4()") shouldBe false + } + } } } diff --git a/designer/src/main/kotlin/org/imdc/extensions/designer/DesignerHook.kt b/designer/src/main/kotlin/org/imdc/extensions/designer/DesignerHook.kt index 4bdc050..9ecc231 100644 --- a/designer/src/main/kotlin/org/imdc/extensions/designer/DesignerHook.kt +++ b/designer/src/main/kotlin/org/imdc/extensions/designer/DesignerHook.kt @@ -13,6 +13,7 @@ import org.imdc.extensions.common.UtilitiesExtensions import org.imdc.extensions.common.addPropertyBundle import org.imdc.extensions.common.expressions.IsAvailableFunction import org.imdc.extensions.common.expressions.LogicalPredicate.Companion.registerLogicFunctions +import org.imdc.extensions.common.expressions.UUID4Function @Suppress("unused") class DesignerHook : AbstractDesignerModuleHook() { @@ -50,6 +51,11 @@ class DesignerHook : AbstractDesignerModuleHook() { IsAvailableFunction(), ) registerLogicFunctions() + addFunction( + UUID4Function.NAME, + UUID4Function.CATEGORY, + UUID4Function(), + ) } } } diff --git a/gateway/src/main/kotlin/org/imdc/extensions/gateway/GatewayHook.kt b/gateway/src/main/kotlin/org/imdc/extensions/gateway/GatewayHook.kt index 36cffab..72727b8 100644 --- a/gateway/src/main/kotlin/org/imdc/extensions/gateway/GatewayHook.kt +++ b/gateway/src/main/kotlin/org/imdc/extensions/gateway/GatewayHook.kt @@ -13,6 +13,7 @@ import org.imdc.extensions.common.UtilitiesExtensions import org.imdc.extensions.common.addPropertyBundle import org.imdc.extensions.common.expressions.IsAvailableFunction import org.imdc.extensions.common.expressions.LogicalPredicate.Companion.registerLogicFunctions +import org.imdc.extensions.common.expressions.UUID4Function @Suppress("unused") class GatewayHook : AbstractGatewayModuleHook() { @@ -57,6 +58,11 @@ class GatewayHook : AbstractGatewayModuleHook() { IsAvailableFunction(), ) registerLogicFunctions() + addFunction( + UUID4Function.NAME, + UUID4Function.CATEGORY, + UUID4Function(), + ) } }