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

[NU-1960] API for messages preview in source #7510

Merged
merged 37 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
87efa6b
somehow working version
pielas Jan 29, 2025
2b3d371
v2
pielas Jan 29, 2025
223f081
v3
pielas Feb 3, 2025
be5be16
tweaks
pielas Feb 3, 2025
0b31110
fix
pielas Feb 3, 2025
386b735
fix
pielas Feb 3, 2025
0f74054
Merge remote-tracking branch 'origin/staging' into feature/NU-1960-me…
pielas Feb 3, 2025
9daa394
added tests
pielas Feb 3, 2025
cb4a7d1
fixes
pielas Feb 3, 2025
772ea67
review fixes
pielas Feb 6, 2025
50a4a4e
review fixes
pielas Feb 6, 2025
968cf06
fixes
pielas Feb 6, 2025
f84082e
fixes
pielas Feb 6, 2025
66a2522
fixes
pielas Feb 6, 2025
bad3788
renamed error outputs
pielas Feb 7, 2025
680da5d
Added dedicated error for TooManySamplesRequested
pielas Feb 7, 2025
1e0d211
formatting fix
pielas Feb 7, 2025
011ee11
refactor
pielas Feb 7, 2025
c3d1ecb
refactor
pielas Feb 7, 2025
360e361
fixes
pielas Feb 7, 2025
fa600ee
openapi yaml
pielas Feb 7, 2025
45e3288
fix
pielas Feb 7, 2025
75dc7bf
Merge branch 'staging' into feature/NU-1960-messages-preview-in-source
pielas Feb 7, 2025
579da3f
removed unused code
pielas Feb 7, 2025
8dfabad
fix
pielas Feb 7, 2025
c10afc7
test fixes
pielas Feb 10, 2025
74e6cb8
Merge branch 'staging' into feature/NU-1960-messages-preview-in-source
pielas Feb 10, 2025
b1185cf
Merge branch 'staging' into feature/NU-1960-messages-preview-in-source
pielas Feb 10, 2025
3b3a772
Merge branch 'staging' into feature/NU-1960-messages-preview-in-source
pielas Feb 10, 2025
6b63a9a
Merge branch 'staging' into feature/NU-1960-messages-preview-in-source
pielas Feb 10, 2025
41eeb9f
test fixes
pielas Feb 10, 2025
80aa97c
test fixes
pielas Feb 10, 2025
91938ce
test fixes
pielas Feb 10, 2025
6cb3e68
Merge branch 'staging' into feature/NU-1960-messages-preview-in-source
pielas Feb 10, 2025
e22903e
restored old code for handle basic flow
pielas Feb 10, 2025
22cd3f4
Merge remote-tracking branch 'origin/feature/NU-1960-messages-preview…
pielas Feb 10, 2025
5f91136
added timeout to test
pielas Feb 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import pl.touk.nussknacker.engine.ModelData
import pl.touk.nussknacker.engine.api.graph.{ProcessProperties, ScenarioGraph}
import pl.touk.nussknacker.engine.api.process.{ProcessName, ProcessingType}
import pl.touk.nussknacker.engine.api.typed.typing.TypingResult
import pl.touk.nussknacker.engine.graph.node.SourceNodeData
import pl.touk.nussknacker.engine.spel.ExpressionSuggestion
import pl.touk.nussknacker.restmodel.definition.UIValueParameter
import pl.touk.nussknacker.restmodel.scenariodetails.ScenarioWithDetails
Expand All @@ -16,6 +17,7 @@ import pl.touk.nussknacker.ui.api.BaseHttpService.CustomAuthorizationError
import pl.touk.nussknacker.ui.api.description.NodesApiEndpoints
import pl.touk.nussknacker.ui.api.description.NodesApiEndpoints.Dtos
import pl.touk.nussknacker.ui.api.description.NodesApiEndpoints.Dtos.NodesError.{
FetchLatestRecordsError,
MalformedTypingResult,
NoPermission,
NoProcessingType,
Expand All @@ -34,11 +36,12 @@ import pl.touk.nussknacker.ui.api.description.NodesApiEndpoints.Dtos.{
decodeVariableTypes,
prepareTypingResultDecoder
}
import pl.touk.nussknacker.ui.api.utils.ScenarioHttpServiceExtensions
import pl.touk.nussknacker.ui.api.utils.ScenarioDetailsOps._
import pl.touk.nussknacker.ui.api.utils.ScenarioHttpServiceExtensions
import pl.touk.nussknacker.ui.process.ProcessService
import pl.touk.nussknacker.ui.process.processingtype.provider.ProcessingTypeDataProvider
import pl.touk.nussknacker.ui.process.repository.ProcessDBQueryRepository.ProcessNotFoundError
import pl.touk.nussknacker.ui.process.test.ScenarioTestService
import pl.touk.nussknacker.ui.security.api.{AuthManager, LoggedUser}
import pl.touk.nussknacker.ui.suggester.ExpressionSuggester
import pl.touk.nussknacker.ui.validation.{NodeValidator, ParametersValidator, UIProcessValidator}
Expand All @@ -52,6 +55,7 @@ class NodesApiHttpService(
processingTypeToNodeValidator: ProcessingTypeDataProvider[NodeValidator, _],
processingTypeToExpressionSuggester: ProcessingTypeDataProvider[ExpressionSuggester, _],
processingTypeToParametersValidator: ProcessingTypeDataProvider[ParametersValidator, _],
processingTypeToScenarioTestServices: ProcessingTypeDataProvider[ScenarioTestService, _],
protected override val scenarioService: ProcessService
)(override protected implicit val executionContext: ExecutionContext)
extends BaseHttpService(authManager)
Expand Down Expand Up @@ -144,6 +148,39 @@ class NodesApiHttpService(
}
}

expose {
nodesApiEndpoints.fetchLatestRecordsForNodeEndpoint
.serverSecurityLogic(authorizeKnownUser[NodesError])
.serverLogicEitherT { implicit loggedUser =>
{ case (scenarioName, numberOfRecords, fetchLatestRecordsDto) =>
arkadius marked this conversation as resolved.
Show resolved Hide resolved
for {
scenarioWithDetails <- getScenarioWithDetailsByName(scenarioName)
scenarioTestService = processingTypeToScenarioTestServices.forProcessingTypeUnsafe(
scenarioWithDetails.processingType
)
sourceNodeData <- EitherT.fromEither[Future](fetchLatestRecordsDto.nodeData match {
case source: SourceNodeData => Right(source)
case other =>
Left(FetchLatestRecordsError(s"Expected SourceNodeData but got: ${other.getClass.getSimpleName}"))
})
parametersDefinition <- EitherT[Future, NodesError, String](
scenarioTestService.getDataFromSource(
fetchLatestRecordsDto.processProperties.toMetaData(scenarioName),
sourceNodeData,
numberOfRecords
) match {
case Left(error) =>
logger.error(s"Error during fetching latest records for node=[${sourceNodeData.id}]: $error")
Future(Left(FetchLatestRecordsError(error)))
case Right(rawScenarioTestData) =>
Future(Right(rawScenarioTestData.content))
}
)
} yield parametersDefinition
}
}
}

expose {
nodesApiEndpoints.parametersValidationEndpoint
.serverSecurityLogic(authorizeKnownUser[NodesError])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import io.circe.{Decoder, Encoder, Json, KeyDecoder, KeyEncoder}
import org.springframework.util.ClassUtils
import pl.touk.nussknacker.engine.additionalInfo.{AdditionalInfo, MarkdownAdditionalInfo}
import pl.touk.nussknacker.engine.api.CirceUtil._
import pl.touk.nussknacker.engine.api.{LayoutData, ProcessAdditionalFields}
import pl.touk.nussknacker.engine.api.{LayoutData, ProcessAdditionalFields, StreamMetaData}
import pl.touk.nussknacker.engine.api.definition.{
FixedExpressionValue,
FixedExpressionValueWithIcon,
Expand Down Expand Up @@ -54,6 +54,7 @@ import pl.touk.nussknacker.security.AuthCredentials
import pl.touk.nussknacker.ui.api.TapirCodecs.ScenarioGraphCodec._
import pl.touk.nussknacker.ui.api.TapirCodecs.ScenarioNameCodec._
import pl.touk.nussknacker.ui.api.description.NodesApiEndpoints.Dtos.NodesError.{
FetchLatestRecordsError,
MalformedTypingResult,
NoProcessingType,
NoScenario
Expand Down Expand Up @@ -349,6 +350,63 @@ class NodesApiEndpoints(auth: EndpointInput[AuthCredentials]) extends BaseEndpoi
.withSecurity(auth)
}

lazy val fetchLatestRecordsForNodeEndpoint: SecuredEndpoint[
(ProcessName, Int, FetchLatestRecordsRequestDto),
NodesError,
String,
Any
] = {
baseNuApiEndpoint
.summary("Fetch latest records for specific node")
.tag("Nodes")
.post
.in(
"nodes" / path[ProcessName]("scenarioName") / "fetchLatestRecordsForNode" / path[Int](
arkadius marked this conversation as resolved.
Show resolved Hide resolved
"numberOfRecords"
)
)
.in(
jsonBody[FetchLatestRecordsRequestDto]
.example(
Example.of(
summary = Some("Basic fetch request"),
value = FetchLatestRecordsRequestDto(
ProcessProperties(StreamMetaData()),
Source("sourceId", SourceRef("source", List.empty), None)
)
)
)
)
.out(
statusCode(Ok).and(
stringBody
.examples(
List(
Example.of(
summary = Some("Simple scenario test data in json stringify form"),
value = "{name: John}"
)
)
)
)
)
.errorOut(
oneOf[NodesError](
fetchLatestRecordsErrorExample,
arkadius marked this conversation as resolved.
Show resolved Hide resolved
noScenarioExample
)
)
.withSecurity(auth)
}

private val simpleGraphExample: Example[ScenarioGraph] = Example.of(
ScenarioGraph(
ProcessProperties(StreamMetaData()),
List(),
List(),
)
)

lazy val parametersValidationEndpoint: SecuredEndpoint[
(ProcessingType, ParametersValidationRequestDto),
NodesError,
Expand Down Expand Up @@ -561,6 +619,18 @@ object NodesApiEndpoints {
)
)

val fetchLatestRecordsErrorExample: EndpointOutput.OneOfVariant[FetchLatestRecordsError] =
oneOfVariantFromMatchType(
NotFound,
plainBody[FetchLatestRecordsError]
.example(
Example.of(
summary = Some("Fetching error"),
value = FetchLatestRecordsError("Fetching error")
)
)
)

val malformedTypingResultExample: EndpointOutput.OneOfVariant[MalformedTypingResult] =
oneOfVariantFromMatchType(
BadRequest,
Expand Down Expand Up @@ -1472,6 +1542,7 @@ object NodesApiEndpoints {
sealed trait NodesError

object NodesError {
final case class FetchLatestRecordsError(msg: String) extends NodesError
arkadius marked this conversation as resolved.
Show resolved Hide resolved
final case class NoScenario(scenarioName: ProcessName) extends NodesError
final case class NoProcessingType(processingType: ProcessingType) extends NodesError
final case object NoPermission extends NodesError with CustomAuthorizationError
Expand All @@ -1495,8 +1566,20 @@ object NodesApiEndpoints {
)
}

implicit val fetchLatestRecordsErrorCodec: Codec[String, FetchLatestRecordsError, CodecFormat.TextPlain] = {
BaseEndpointDefinitions.toTextPlainCodecSerializationOnly[FetchLatestRecordsError](e =>
s"Error during fetching latest records: \n${e.msg}"
)
}

}

@derive(schema, encoder, decoder)
final case class FetchLatestRecordsRequestDto(
processProperties: ProcessProperties,
nodeData: NodeData
)

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package pl.touk.nussknacker.ui.process.test

import com.carrotsearch.sizeof.RamUsageEstimator
import com.typesafe.scalalogging.LazyLogging
import pl.touk.nussknacker.engine.api.ProcessVersion
import pl.touk.nussknacker.engine.api.definition.{DualParameterEditor, Parameter, StringParameterEditor}
import pl.touk.nussknacker.engine.api.editor.DualEditorMode
import pl.touk.nussknacker.engine.api.graph.ScenarioGraph
import pl.touk.nussknacker.engine.api.test.ScenarioTestData
import pl.touk.nussknacker.engine.api.typed.typing.Typed
import pl.touk.nussknacker.engine.api.{MetaData, ProcessVersion}
import pl.touk.nussknacker.engine.canonicalgraph.CanonicalProcess
import pl.touk.nussknacker.engine.definition.test.{TestInfoProvider, TestingCapabilities}
import pl.touk.nussknacker.engine.graph.node.SourceNodeData
import pl.touk.nussknacker.engine.testmode.TestProcess.TestResults
import pl.touk.nussknacker.restmodel.definition.UISourceParameters
import pl.touk.nussknacker.ui.api.TestDataSettings
Expand Down Expand Up @@ -85,6 +86,16 @@ class ScenarioTestService(
} yield rawTestData
}

def getDataFromSource(
metaData: MetaData,
sourceNodeData: SourceNodeData,
size: Int
): Either[String, RawScenarioTestData] = {
testInfoProvider.generateTestDataForSource(metaData, sourceNodeData, size).flatMap { generatedData =>
preliminaryScenarioTestDataSerDe.serialize(generatedData)
}
}

def performTest(
scenarioGraph: ScenarioGraph,
processVersion: ProcessVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ class AkkaHttpBasedRouteProvider(
processingTypeToParametersValidator = processingTypeDataProvider.mapValues(v =>
new ParametersValidator(v.designerModelData.modelData, v.deploymentData.scenarioPropertiesConfig.keys)
),
processingTypeToScenarioTestServices = scenarioTestService,
scenarioService = processService,
)

Expand Down
Loading