diff --git a/designer/server/src/main/scala/pl/touk/nussknacker/ui/api/ManagementResources.scala b/designer/server/src/main/scala/pl/touk/nussknacker/ui/api/ManagementResources.scala index 59636638542..c7ff59f1f41 100644 --- a/designer/server/src/main/scala/pl/touk/nussknacker/ui/api/ManagementResources.scala +++ b/designer/server/src/main/scala/pl/touk/nussknacker/ui/api/ManagementResources.scala @@ -91,6 +91,28 @@ class ManagementResources( private implicit final val plainBytes: FromEntityUnmarshaller[Array[Byte]] = Unmarshaller.byteArrayUnmarshaller private implicit final val plainString: FromEntityUnmarshaller[String] = Unmarshaller.stringUnmarshaller + // TODO: This is workaround for touk/nussknacker-example-scenarios-library that deploys tests with plain text comment. + // https://github.com/TouK/nussknacker-scenario-examples-library/pull/7 + private def deployRequestEntity: Directive1[RunDeploymentRequest] = { + entity(as[Option[String]]).flatMap { optStr => + { + optStr match { + case None => provide(RunDeploymentRequest(None, None)) + case Some(body) => + io.circe.parser.parse(body) match { + case Right(json) => + json.as[RunDeploymentRequest] match { + case Right(request) => provide(request) + case Left(notValidDeployRequest) => + reject(MalformedRequestContentRejection("lorem ipsum", notValidDeployRequest)) + } + case Left(notJson) => provide(RunDeploymentRequest(None, Some(body))) + } + } + } + } + } + def securedRoute(implicit user: LoggedUser): Route = { pathPrefix("adminProcessManagement") { path("snapshot" / ProcessNameSegment) { processName => @@ -120,7 +142,7 @@ class ManagementResources( } } ~ path("deploy" / ProcessNameSegment) { processName => - (post & processId(processName) & entity(as[RunDeploymentRequest]) & parameters(Symbol("savepointPath"))) { + (post & processId(processName) & deployRequestEntity & parameters(Symbol("savepointPath"))) { (processIdWithName, request, savepointPath) => canDeploy(processIdWithName) { complete { @@ -143,7 +165,7 @@ class ManagementResources( pathPrefix("processManagement") { path("deploy" / ProcessNameSegment) { processName => - (post & processId(processName) & entity(as[RunDeploymentRequest])) { (processIdWithName, request) => + (post & processId(processName) & deployRequestEntity) { (processIdWithName, request) => canDeploy(processIdWithName) { complete { measureTime("deployment", metricRegistry) { diff --git a/designer/server/src/test/scala/pl/touk/nussknacker/test/base/it/NuResourcesTest.scala b/designer/server/src/test/scala/pl/touk/nussknacker/test/base/it/NuResourcesTest.scala index 2d96431f03a..81d2b100e45 100644 --- a/designer/server/src/test/scala/pl/touk/nussknacker/test/base/it/NuResourcesTest.scala +++ b/designer/server/src/test/scala/pl/touk/nussknacker/test/base/it/NuResourcesTest.scala @@ -344,6 +344,17 @@ trait NuResourcesTest ) ~> withPermissions(deployRoute(), Permission.Deploy, Permission.Read) + // TODO: See comment in ManagementResources.deployRequestEntity + protected def deployProcessCommentOnly( + processName: ProcessName, + comment: Option[String] = None + ): RouteTestResult = + Post( + s"/processManagement/deploy/$processName", + HttpEntity(ContentTypes.`application/json`, comment.getOrElse("")) + ) ~> + withPermissions(deployRoute(), Permission.Deploy, Permission.Read) + protected def cancelProcess( processName: ProcessName, comment: Option[String] = None diff --git a/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ManagementResourcesSpec.scala b/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ManagementResourcesSpec.scala index f4a0efee87c..52eb611b827 100644 --- a/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ManagementResourcesSpec.scala +++ b/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ManagementResourcesSpec.scala @@ -126,6 +126,34 @@ class ManagementResourcesSpec } } + // TODO: To be removed. See comment in ManagementResources.deployRequestEntity + test("deploys and cancels with plain text comment") { + saveCanonicalProcessAndAssertSuccess(ProcessTestData.sampleScenario) + deployProcessCommentOnly( + ProcessTestData.sampleScenario.name, + comment = Some("deployComment") + ) ~> checkThatEventually { + getProcess(processName) ~> check { + val processDetails = responseAs[ScenarioWithDetails] + processDetails.lastStateAction.exists(_.actionName == ScenarioActionName.Deploy) shouldBe true + } + } + } + + // TODO: To be removed. See comment in ManagementResources.deployRequestEntity + test("deploys and cancels with plain text no comment") { + saveCanonicalProcessAndAssertSuccess(ProcessTestData.sampleScenario) + deployProcessCommentOnly( + ProcessTestData.sampleScenario.name, + comment = None + ) ~> checkThatEventually { + getProcess(processName) ~> check { + val processDetails = responseAs[ScenarioWithDetails] + processDetails.lastStateAction.exists(_.actionName == ScenarioActionName.Deploy) shouldBe true + } + } + } + test("deploys and cancels with comment") { saveCanonicalProcessAndAssertSuccess(ProcessTestData.sampleScenario) deployProcess( diff --git a/docs/Changelog.md b/docs/Changelog.md index ef7c6979fc8..135f9e9c2ab 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -55,6 +55,8 @@ * [#7446](https://github.com/TouK/nussknacker/pull/7446) Small changes regarding node errors in fragments used in scenarios: * Fragment error node tips in scenarios are now clickable and open problematic node edit window in a new tab. * Fragment nodes are now highlighted when they contain nodes with errors. +* [#6860](https://github.com/TouK/nussknacker/pull/6860) Ability to configure deploy action parameters and apply those parameters in deploy http request. + Kafka source has "offset reset strategy" parameter that controls starting point for reading events. ## 1.18 diff --git a/docs/MigrationGuide.md b/docs/MigrationGuide.md index fd2975f560e..76b301d3197 100644 --- a/docs/MigrationGuide.md +++ b/docs/MigrationGuide.md @@ -40,6 +40,8 @@ To see the biggest differences please consult the [changelog](Changelog.md). * [#7379](https://github.com/TouK/nussknacker/pull/7379) Removed CustomAction mechanism. If there were any custom actions defined in some custom DeploymentManager implementation, they should be modified to use the predefined set of actions or otherwise replaced by custom links and handled outside Nussknacker. +* [#6860](https://github.com/TouK/nussknacker/pull/6860) Deploy http request requires valid json in request body (see `RunDeploymentRequest`) instead of plain text, e.g. `{"comment": "example text"}`. + For KafkaFlinkSource it is possible to provide optional deployment parameter, e.g. `{"comment": "example text", "nodesDeploymentData": {"my_source_node_id": {"offsetResetStrategy": "Reset"}}}` ### Code API changes * [#7368](https://github.com/TouK/nussknacker/pull/7368) Renamed `PeriodicSourceFactory` to `SampleGeneratorSourceFactory` diff --git a/examples/dev/local-testing.docker-compose.yml b/examples/dev/local-testing.docker-compose.yml index 91accb9c29d..7b9782044fe 100644 --- a/examples/dev/local-testing.docker-compose.yml +++ b/examples/dev/local-testing.docker-compose.yml @@ -200,7 +200,7 @@ services: deploy: resources: limits: - memory: 4096M + memory: 1024M telegraf: image: telegraf:1.30.2