Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge staging to master to deploy to nussknacker demo #7366

Closed
wants to merge 84 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
c4fb350
version bump to 1.19-SNAPSHOT
arkadius Oct 30, 2024
6d63f6d
NU-1661 Remove focus from input in a dialog on esc keyboard button cl…
Dzuming Oct 31, 2024
acce220
kafka: switching from zk to kraft in tests (#5461)
arkadius Oct 31, 2024
36a6af2
Merge branch 'release/1.18' into staging
arkadius Nov 6, 2024
58f8185
Merge pull request #7126 from TouK/1.18-port
arkadius Nov 6, 2024
4d18074
Added work directory for local development purpose
arkadius Nov 7, 2024
12becf5
restored gitignore entry
arkadius Nov 7, 2024
03566ab
Merge pull request #7131 from TouK/add-work-directory
arkadius Nov 8, 2024
478bd88
Merge branch 'release/1.18' into staging
arkadius Nov 12, 2024
15a4f9d
Merge pull request #7139 from TouK/1.18-ports-2
arkadius Nov 12, 2024
3779aab
Merge branch 'release/1.18' into staging
arkadius Nov 14, 2024
d431297
bump actions github artifact plugins (#7146)
mslabek Nov 14, 2024
0356376
[NU-7142] Lift TypingResult for dicts (#7145)
DeamonDev Nov 14, 2024
e9d9436
Merge pull request #7152 from TouK/1.18-ports3
arkadius Nov 14, 2024
9ea303c
Merge remote-tracking branch 'origin/release/1.18' into staging
arkadius Nov 15, 2024
14306e2
Merge pull request #7161 from TouK/1.18-ports4
arkadius Nov 16, 2024
5ebf989
NU-1848: Improve missing Flink Kafka Source / Sink TypeInformation (#…
lciolecki Nov 18, 2024
580adec
Fix deployments for scenarios with dict editors after model reload (#…
Elmacioro Nov 19, 2024
1539ae5
[Nu-1858] separate properties and node details (#7129)
Dzuming Nov 19, 2024
14a9a75
[NU-1800] Add TemplateEvaluationResult to evaluate SpEL expression pa…
mslabek Nov 20, 2024
d5154a3
[NU-7164] Add basic parser for fragment input definitions (#7167)
DeamonDev Nov 21, 2024
e440a86
Merge branch 'release/1.18' into staging
arkadius Nov 21, 2024
383b4d5
Revert "[NU-7164] Add basic parser for fragment input definitions (#7…
mslabek Nov 21, 2024
fca1a27
fix spel template default expression (#7198)
mslabek Nov 21, 2024
e122eff
Merge remote-tracking branch 'origin/staging' into 1.18-ports5
arkadius Nov 21, 2024
0d6a9c7
Merge pull request #7209 from TouK/1.18-ports5
arkadius Nov 21, 2024
a68f84c
Merge branch 'release/1.18' into staging
arkadius Nov 21, 2024
9b4432c
Merge pull request #7211 from TouK/1.18-ports6
arkadius Nov 21, 2024
5e5bf70
[NU-1823] Kafka source without topic schema (#7066)
ForrestFairy Nov 22, 2024
80fe7a9
Merge branch 'release/1.18' into staging
arkadius Nov 22, 2024
ec8c461
Merge pull request #7221 from TouK/1.18-ports7
arkadius Nov 22, 2024
fcebd61
Toolbar additional parameters (#7168)
JulianWielga Nov 22, 2024
12daa1b
[NU-7164] Add basic parser for fragment input definitions V2 (#7228)
DeamonDev Nov 25, 2024
656cac2
Merge branch 'release/1.18' into 1.18-ports8
arkadius Nov 25, 2024
deaec57
Merge pull request #7233 from TouK/1.18-ports8
arkadius Nov 25, 2024
6d39ce8
Migrate SizeAndTimeBasedFNATP to SizeAndTimeBasedRollingPolicy
piotrp Nov 25, 2024
a306cab
Add missing space in error message
piotrp Nov 25, 2024
0fc6d66
Use component name instead of id in statistics (#7238)
ForrestFairy Nov 26, 2024
1a4c2d0
Scale fields in components (#7213)
Diamekod0221 Nov 26, 2024
aa609c0
Fix Kafka and periodic activity flaky tests (#7223)
mslabek Nov 27, 2024
0f94b80
Revert "Scale fields in components (#7213)" (#7253)
Diamekod0221 Nov 27, 2024
af8d3d7
[NU-1897] nussknacker-components-api: remove dependency to async-http…
arkadius Nov 28, 2024
02bcde6
[NU-1897] flink-executor and lite-runtime modules: Added compile-time…
arkadius Nov 28, 2024
ed735a3
Scale name in components fixed (#7258)
Diamekod0221 Nov 28, 2024
55d7f3e
Change subclass determiner to assignability determiner (#7246)
Diamekod0221 Nov 28, 2024
9266517
fix RemoteAuthStrategy (#7263)
JulianWielga Nov 28, 2024
3006060
[NU-1823] Fix for schemaless topics in kafka source/sink (#7232)
ForrestFairy Nov 29, 2024
13e570b
[Nu-7231] Add possibility for generic types (#7242)
DeamonDev Nov 29, 2024
d2b0b33
scroll view to cursor (#7269)
JulianWielga Dec 2, 2024
6f09c83
Savepoint deserialization fixup - The class is an inner class, but no…
raphaelsolarski Dec 3, 2024
5a4bbe5
providerType config and idle source (#7274)
ZbyszekMM Dec 3, 2024
4531af0
Merge branch 'release/1.18' into staging
arkadius Dec 3, 2024
ed41530
Merge pull request #7281 from TouK/1.18-ports9
arkadius Dec 3, 2024
9db6f47
Replace "run now" CustomAction with standard action PerformSingleExec…
mgoworko Dec 4, 2024
37580f8
Add notifications related to currently displayed scenario (#7184)
mgoworko Dec 4, 2024
281a5d2
Merge branch 'release/1.18' into staging
arkadius Dec 5, 2024
5b2a777
Merge pull request #7285 from TouK/1.18-ports10
arkadius Dec 5, 2024
b180fce
Merge branch 'release/1.18' into staging
arkadius Dec 9, 2024
abc91a4
Merge pull request #7300 from TouK/1.18-ports11
arkadius Dec 9, 2024
e2a8279
add debug log for schedule deployments for batches (#7302)
DeamonDev Dec 9, 2024
41ce31e
Merge branch 'release/1.18' into staging
arkadius Dec 9, 2024
bb0a0cf
Fix: CI replace image vectorized/redpanda -> redpandadata/redpanda (#…
lciolecki Dec 10, 2024
b0a4c62
add log about latest deployment ids (#7305)
DeamonDev Dec 10, 2024
1f862f2
Aggregate map fix (#7308)
JulianWielga Dec 12, 2024
c46c423
[Fix] Improve periodic dm db queries #7323
mgoworko Dec 12, 2024
76c1ccc
[Fix] Fix notifications to not trigger state update for fragments, fe…
mgoworko Dec 12, 2024
671cc85
Allow "run now" only for currently deployed version, which must be pr…
mgoworko Dec 12, 2024
5c6cbb9
Disable namespace in Kafka component (#7326)
mslabek Dec 13, 2024
364489f
Handle scenario names with spaces when performing migration tests (#7…
piotrp Dec 13, 2024
5da9e12
Remove unused class
piotrp Dec 13, 2024
7b4fafb
Update dependencies: Netty, HikariCP, HSQLDB (#7331)
piotrp Dec 13, 2024
7aa25fb
[NU-1828] OpenAPI enricher: ability to configure common secret for an…
arkadius Dec 17, 2024
d0f0d3e
Use `RichFunction.open(OpenContext)` instead of `RichFunction.open(Co…
piotrp Dec 17, 2024
5069ac1
[NU-1777] "Perform single execution" action was renamed to "Run off s…
coutoPL Dec 17, 2024
2b7211f
Fetch only latest scenario activities for periodic DM (#7344)
mgoworko Dec 17, 2024
7feab59
Remove uses of deprecated methods from RuntimeContext (#7348)
piotrp Dec 17, 2024
5970344
Provide more descriptive validation message for inline maps with non …
DeamonDev Dec 17, 2024
a5d5305
[NU-1828] Processing types configs loader api (#7336)
arkadius Dec 17, 2024
f00c47a
[NU-1921] Add standard deviation and variance aggregations (#7307)
paw787878 Dec 18, 2024
ace3d3c
[NU-1921] Add median aggregator #7321
paw787878 Dec 18, 2024
f9cdc9e
Revert "[NU-1921] Add median aggregator #7321"
Dec 18, 2024
659bc73
[NU-1928] Fix special case for spel toMap extension (#7329)
paw787878 Dec 18, 2024
a8e0a79
Integer dictionary support in fragment inputs (#7341)
mateuszkp96 Dec 18, 2024
1542187
[NU-1828] Processing types configs loader api: possibility to use pro…
arkadius Dec 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
150 changes: 94 additions & 56 deletions build.sbt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package pl.touk.nussknacker.engine.api.parameter

import io.circe.generic.extras.semiauto.{deriveUnwrappedDecoder, deriveUnwrappedEncoder}
import io.circe.{Decoder, Encoder, KeyDecoder, KeyEncoder}

final case class ParameterName(value: String) {
def withBranchId(branchId: String): ParameterName = ParameterName(s"$value for branch $branchId")
}

object ParameterName {
implicit val encoder: Encoder[ParameterName] = deriveUnwrappedEncoder
implicit val decoder: Decoder[ParameterName] = deriveUnwrappedDecoder

implicit val keyEncoder: KeyEncoder[ParameterName] = KeyEncoder.encodeKeyString.contramap(_.value)
implicit val keyDecoder: KeyDecoder[ParameterName] = KeyDecoder.decodeKeyString.map(ParameterName(_))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package pl.touk.nussknacker.engine.api

case class TemplateEvaluationResult(renderedParts: List[TemplateRenderedPart]) {
def renderedTemplate: String = renderedParts.map(_.value).mkString("")
}

sealed trait TemplateRenderedPart {
def value: String
}

object TemplateRenderedPart {
case class RenderedLiteral(value: String) extends TemplateRenderedPart

case class RenderedSubExpression(value: String) extends TemplateRenderedPart
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package pl.touk.nussknacker.engine.api.component

import io.circe.generic.JsonCodec
import pl.touk.nussknacker.engine.api.definition.FixedExpressionValue
import pl.touk.nussknacker.engine.api.parameter.{
ParameterName,
Expand All @@ -24,6 +25,7 @@ object AdditionalUIConfigProvider {
val empty = new DefaultAdditionalUIConfigProvider(Map.empty, Map.empty)
}

@JsonCodec
case class ComponentAdditionalConfig(
parameterConfigs: Map[ParameterName, ParameterAdditionalUIConfig],
icon: Option[String] = None,
Expand All @@ -32,6 +34,7 @@ case class ComponentAdditionalConfig(
disabled: Boolean = false
)

@JsonCodec
case class ParameterAdditionalUIConfig(
required: Boolean,
initialValue: Option[FixedExpressionValue],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package pl.touk.nussknacker.engine.api.component

import io.circe.generic.extras.semiauto.{deriveUnwrappedDecoder, deriveUnwrappedEncoder}
import io.circe.{Decoder, Encoder}
import io.circe.{Decoder, Encoder, KeyDecoder, KeyEncoder}

// TODO This class is used as a work around for the problem that the components are duplicated across processing types.
// We plan to get rid of this. After that, we could replace usages of this class by usage of ComponentId
Expand All @@ -14,6 +14,10 @@ object DesignerWideComponentId {
implicit val encoder: Encoder[DesignerWideComponentId] = deriveUnwrappedEncoder
implicit val decoder: Decoder[DesignerWideComponentId] = deriveUnwrappedDecoder

implicit val keyEncoder: KeyEncoder[DesignerWideComponentId] = KeyEncoder.encodeKeyString.contramap(_.value)
implicit val keyDecoder: KeyDecoder[DesignerWideComponentId] =
KeyDecoder.decodeKeyString.map(DesignerWideComponentId(_))

def apply(value: String): DesignerWideComponentId = new DesignerWideComponentId(value.toLowerCase)

def forBuiltInComponent(componentId: ComponentId): DesignerWideComponentId = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package pl.touk.nussknacker.engine.api.typed

import cats.data.Validated._
import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits.{catsSyntaxValidatedId, _}
import org.apache.commons.lang3.ClassUtils
import pl.touk.nussknacker.engine.api.typed.typing._

/**
* This class determine whether we can assign one type to another type - that is if its the same class, a subclass or can be converted to another type. We provide two modes of conversion -
* 1. Loose conversion is based on the fact that TypingResults are
* sets of possible supertypes with some additional restrictions (like TypedObjectTypingResult). It is basically how SpEL
* can convert things. Like CommonSupertypeFinder it's in the spirit of "Be type safe as much as possible, but also provide some helpful
* conversion for types not in the same jvm class hierarchy like boxed Integer to boxed Long and so on".
* 2. Strict conversion checks whether we can convert to a wider type. Eg only widening numerical types
* are allowed ( Int -> Long). For other types it should work the same as a loose conversion.
*
*/
object AssignabilityDeterminer {

private val javaMapClass = classOf[java.util.Map[_, _]]
private val javaListClass = classOf[java.util.List[_]]
private val arrayOfAnyRefClass = classOf[Array[AnyRef]]

/**
* This method checks if `givenType` can by subclass of `superclassCandidate`
* It will return true if `givenType` is equals to `superclassCandidate` or `givenType` "extends" `superclassCandidate`
*/
def isAssignableLoose(from: TypingResult, to: TypingResult): ValidatedNel[String, Unit] =
isAssignable(from, to, LooseConversionChecker)

def isAssignableStrict(from: TypingResult, to: TypingResult): ValidatedNel[String, Unit] =
isAssignable(from, to, StrictConversionChecker)

private def isAssignable(from: TypingResult, to: TypingResult, conversionChecker: ConversionChecker) = {
(from, to) match {
case (_, Unknown) => ().validNel
case (Unknown, _) => ().validNel
case (TypedNull, other) => isNullAsignableTo(other)
case (_, TypedNull) => s"No type can be subclass of ${TypedNull.display}".invalidNel
case (given: SingleTypingResult, superclass: TypedUnion) =>
isAnyOfAssignableToAnyOf(NonEmptyList.one(given), superclass.possibleTypes, conversionChecker)
case (given: TypedUnion, superclass: SingleTypingResult) =>
isAnyOfAssignableToAnyOf(given.possibleTypes, NonEmptyList.one(superclass), conversionChecker)
case (given: SingleTypingResult, superclass: SingleTypingResult) =>
isSingleAssignableToSingle(given, superclass, conversionChecker)
case (given: TypedUnion, superclass: TypedUnion) =>
isAnyOfAssignableToAnyOf(given.possibleTypes, superclass.possibleTypes, conversionChecker)
}
}

private def isNullAsignableTo(to: TypingResult): ValidatedNel[String, Unit] = to match {
// TODO: Null should not be subclass of typed map that has all values assigned.
case TypedObjectWithValue(_, _) => s"${TypedNull.display} cannot be subclass of type with value".invalidNel
case _ => ().validNel
}

private def isSingleAssignableToSingle(
from: SingleTypingResult,
to: SingleTypingResult,
conversionChecker: ConversionChecker
): ValidatedNel[String, Unit] = {
val objTypeRestriction = isSingleAssignableToTypedClass(from, to.runtimeObjType, conversionChecker)
val typedObjectRestrictions = (_: Unit) =>
to match {
case superclass: TypedObjectTypingResult =>
val givenTypeFields = from match {
case given: TypedObjectTypingResult => given.fields
case _ => Map.empty[String, TypingResult]
}

superclass.fields.toList
.map { case (name, typ) =>
givenTypeFields.get(name) match {
case None =>
s"Field '$name' is lacking".invalidNel
case Some(givenFieldType) =>
condNel(
isAssignable(givenFieldType, typ, conversionChecker).isValid,
(),
s"Field '$name' is of the wrong type. Expected: ${givenFieldType.display}, actual: ${typ.display}"
)
}
}
.foldLeft(().validNel[String])(_.combine(_))
case _ =>
().validNel
}
val dictRestriction = (_: Unit) => {
(from, to) match {
case (given: TypedDict, superclass: TypedDict) =>
condNel(
given.dictId == superclass.dictId,
(),
"The type and the superclass candidate are Dicts with unequal IDs"
)
case (_: TypedDict, _) =>
"The type is a Dict but the superclass candidate not".invalidNel
case (_, _: TypedDict) =>
"The superclass candidate is a Dict but the type not".invalidNel
case _ =>
().validNel
}
}
val taggedValueRestriction = (_: Unit) => {
(from, to) match {
case (givenTaggedValue: TypedTaggedValue, superclassTaggedValue: TypedTaggedValue) =>
condNel(
givenTaggedValue.tag == superclassTaggedValue.tag,
(),
s"Tagged values have unequal tags: ${givenTaggedValue.tag} and ${superclassTaggedValue.tag}"
)
case (_: TypedTaggedValue, _) => ().validNel
case (_, _: TypedTaggedValue) =>
s"The type is not a tagged value".invalidNel
case _ => ().validNel
}
}
// Type like Integer can be subclass of Integer{5}, because Integer could
// possibly have value of 5, that would make it subclass of Integer{5}.
// This allows us to supply unknown Integer to function that requires
// Integer{5}.
val dataValueRestriction = (_: Unit) => {
(from, to) match {
case (TypedObjectWithValue(_, givenValue), TypedObjectWithValue(_, candidateValue))
if givenValue == candidateValue =>
().validNel
case (TypedObjectWithValue(_, givenValue), TypedObjectWithValue(_, candidateValue)) =>
s"Types with value have different values: $givenValue and $candidateValue".invalidNel
case _ => ().validNel
}
}
objTypeRestriction andThen
(typedObjectRestrictions combine dictRestriction combine taggedValueRestriction combine dataValueRestriction)
}

private def isSingleAssignableToTypedClass(
from: SingleTypingResult,
to: TypedClass,
conversionChecker: ConversionChecker
): ValidatedNel[String, Unit] = {
def typeParametersMatches(givenClass: TypedClass, superclassCandidate: TypedClass) = {
def canBeSubOrSuperclass(givenClassParam: TypingResult, superclassParam: TypingResult) =
condNel(
isAssignable(givenClassParam, superclassParam, conversionChecker).isValid ||
isAssignable(superclassParam, givenClassParam, conversionChecker).isValid,
(),
f"None of ${givenClassParam.display} and ${superclassParam.display} is a subclass of another"
)

(givenClass, superclassCandidate) match {
case (TypedClass(_, givenElementParam :: Nil), TypedClass(superclass, superclassParam :: Nil))
// Array are invariant but we have built-in conversion between array types - this check should be moved outside this class when we move away canBeConvertedTo as well
if javaListClass.isAssignableFrom(superclass) || arrayOfAnyRefClass.isAssignableFrom(superclass) =>
isAssignable(givenElementParam, superclassParam, conversionChecker)
case (
TypedClass(_, givenKeyParam :: givenValueParam :: Nil),
TypedClass(superclass, superclassKeyParam :: superclassValueParam :: Nil)
) if javaMapClass.isAssignableFrom(superclass) =>
// Map's key generic param is invariant. We can't just check givenKeyParam == superclassKeyParam because of Unknown type which is a kind of wildcard
condNel(
isAssignable(givenKeyParam, superclassKeyParam, conversionChecker).isValid &&
isAssignable(superclassKeyParam, givenKeyParam, conversionChecker).isValid,
(),
s"Key types of Maps ${givenKeyParam.display} and ${superclassKeyParam.display} are not equals"
) andThen (_ => isAssignable(givenValueParam, superclassValueParam, conversionChecker))
case _ =>
// for unknown types we are lax - the generic type may be co- contra- or in-variant - and we don't want to
// return validation errors in this case. It's better to accept to much than too little
condNel(
superclassCandidate.params.zip(givenClass.params).forall { case (superclassParam, givenClassParam) =>
canBeSubOrSuperclass(givenClassParam, superclassParam).isValid
},
(),
s"Wrong type parameters"
)
}
}
val givenClass = from.runtimeObjType

val equalClassesOrCanAssign =
condNel(
givenClass == to,
(),
f"${givenClass.display} and ${to.display} are not the same"
) orElse
isAssignable(givenClass.klass, to.klass)

val canBeSubclass = equalClassesOrCanAssign andThen (_ => typeParametersMatches(givenClass, to))
canBeSubclass orElse conversionChecker.isConvertable(from, to)
}

private def isAnyOfAssignableToAnyOf(
from: NonEmptyList[SingleTypingResult],
to: NonEmptyList[SingleTypingResult],
conversionChecker: ConversionChecker
): ValidatedNel[String, Unit] = {
// Would be more safety to do givenTypes.forAll(... superclassCandidates.exists ...) - we wil protect against
// e.g. (String | Int).isAnyOfAssignableToAnyOf(String) which can fail in runtime for Int, but on the other hand we can't block user's intended action.
// He/she could be sure that in this type, only String will appear. He/she also can't easily downcast (String | Int) to String so leaving here
// "double exists" looks like a good tradeoff
condNel(
from.exists(given => to.exists(isSingleAssignableToSingle(given, _, conversionChecker).isValid)),
(),
s"""None of the following types:
|${from.map(" - " + _.display).toList.mkString(",\n")}
|can be a subclass of any of:
|${to.map(" - " + _.display).toList.mkString(",\n")}""".stripMargin
)
}

// we use explicit autoboxing = true flag, as ClassUtils in commons-lang3:3.3 (used in Flink) cannot handle JDK 11...
private def isAssignable(from: Class[_], to: Class[_]): ValidatedNel[String, Unit] =
condNel(ClassUtils.isAssignable(from, to, true), (), s"$to is not assignable from $from")

// TODO: Conversions should be checked during typing, not during generic usage of TypingResult.canBeSubclassOf(...)
private sealed trait ConversionChecker {

def isConvertable(
from: SingleTypingResult,
to: TypedClass
): ValidatedNel[String, Unit]

}

private object StrictConversionChecker extends ConversionChecker {

override def isConvertable(
from: SingleTypingResult,
to: TypedClass
): ValidatedNel[String, Unit] = {
val errMsgPrefix =
s"${from.runtimeObjType.display} cannot be strictly converted to ${to.display}"
condNel(TypeConversionHandler.canBeStrictlyConvertedTo(from, to), (), errMsgPrefix)
}

}

private object LooseConversionChecker extends ConversionChecker {

override def isConvertable(
from: SingleTypingResult,
to: TypedClass
): ValidatedNel[String, Unit] = {
val errMsgPrefix = s"${from.runtimeObjType.display} cannot be converted to ${to.display}"
condNel(TypeConversionHandler.canBeLooselyConvertedTo(from, to), (), errMsgPrefix)
}

}

}
Loading
Loading