Skip to content

Commit

Permalink
Added Worker implementation to 04-worker-c7spring.
Browse files Browse the repository at this point in the history
  • Loading branch information
pme123 committed Dec 27, 2024
1 parent 2de4306 commit 1c7b7e5
Show file tree
Hide file tree
Showing 14 changed files with 516 additions and 16 deletions.
134 changes: 133 additions & 1 deletion 00-docs/src/docs/company/03-worker.md
Original file line number Diff line number Diff line change
@@ -1 +1,133 @@
# 03-worker
# 03-worker
Use this to add Company specific Worker stuff like the configuration of the auth method.

@:callout(info)
Workers are a bit more complex as there is a specific implementation you have to provide.

This will hopefully be simplified in the future.

For now, you have to provide a couple of files, as explained below.
@:@

The following structure is generated by `./helperCompany.scala init`:

```bash
03-worker/src
| main/resources
| main/scala/company/worker
| | CompanyEngineContext.scala
| | CompanyPasswordFlow.scala
| | CompanyRestApiClient.scala
| | CompanyWorkerHandler.scala
| test/scala/company/worker
```

## CompanyEngineContext
Depending on the Camunda Engine and Authentication you use, you have to provide the EngineContext.

```scala
package mycompany.camundala.worker

import camundala.camunda7.worker.Camunda7Context
import scala.compiletime.uninitialized
import scala.reflect.ClassTag

@SpringConfiguration
class CompanyEngineContext extends Camunda7Context:

@Autowired()
var restApiClient: CompanyRestApiClient = uninitialized

override def sendRequest[ServiceIn: Encoder, ServiceOut: Decoder: ClassTag](
request: RunnableRequest[ServiceIn]
): SendRequestType[ServiceOut] =
restApiClient.sendRequest(request)

end CompanyEngineContext
```
Basically you override the sendRequest to use your RestApiClient with the specific auth-method.

## CompanyPasswordFlow
Configure the Token Service - this is tested only with Keycloak.

```scala
package mycompany.camundala.worker

import camundala.camunda7.worker.oauth.OAuthPasswordFlow

trait CompanyPasswordFlow extends OAuthPasswordFlow:

lazy val fssoRealm: String = sys.env.getOrElse("FSSO_REALM", "myRealm")
// default is a local keycloak server on colime docker environment
lazy val fssoBaseUrl = sys.env.getOrElse("FSSO_BASE_URL", s"http://host.lima.internal:8090")

override lazy val client_id = sys.env.getOrElse("FSSO_CLIENT_NAME", "myClientKey")
override lazy val client_secret = sys.env.getOrElse("FSSO_CLIENT_SECRET", "myClientSecret")
override lazy val scope = sys.env.getOrElse("FSSO_SCOPE", "myScope")
override lazy val username = sys.env.getOrElse("FSSO_TECHUSER_NAME", "myTechUser")
override lazy val password = sys.env.getOrElse("FSSO_TECHUSER_PASSWORD", "myTechUserPassword")

end CompanyPasswordFlow
```
## CompanyRestApiClient
Some specific configuration or authentication for the RestApiClient.

```scala
package mycompany.camundala.worker

import camundala.camunda7.worker.RestApiClient
import camundala.worker.CamundalaWorkerError.*
import sttp.client3.*

@SpringConfiguration
class CompanyRestApiClient extends RestApiClient, CompanyPasswordFlow:

override protected def auth(
request: Request[Either[String, String], Any]
)(using context: EngineRunContext
): Either[ServiceAuthError, Request[Either[String, String], Any]] =
tokenService.adminToken()
.map:
request.addToken
end auth

end CompanyRestApiClient
```
## CompanyWorkerHandler

The Company's base class, you can provide super classes for each Worker type.
See [Workers] for more information on these types.

Example (generated by `./helperCompany.scala init`):

```scala
package mycompany.camundala.worker

import camundala.camunda7.worker.C7WorkerHandler
import scala.reflect.ClassTag

/**
* Add here company specific stuff, to run the Workers.
* You also define the implementation of the WorkerHandler here.
*/
trait CompanyWorkerHandler extends C7WorkerHandler

trait CompanyInitWorkerDsl[
In <: Product: InOutCodec,
Out <: Product: InOutCodec,
InitIn <: Product: InOutCodec,
InConfig <: Product: InOutCodec
] extends CompanyWorkerHandler, InitWorkerDsl[In, Out, InitIn, InConfig]

trait CompanyCustomWorkerDsl[
In <: Product: InOutCodec,
Out <: Product: InOutCodec
] extends CompanyWorkerHandler, CustomWorkerDsl[In, Out]

trait CompanyServiceWorkerDsl[
In <: Product: InOutCodec,
Out <: Product: InOutCodec,
ServiceIn: InOutEncoder,
ServiceOut: InOutDecoder: ClassTag
] extends CompanyWorkerHandler, ServiceWorkerDsl[In, Out, ServiceIn, ServiceOut]
```
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ case class CompanySbtGenerator()(using
|""".stripMargin

private lazy val settings =
s"""// $helperCompanyDoNotAdjustText
s"""$helperCompanyDoNotAdjustText
|
|import com.typesafe.config.ConfigFactory
|import laika.ast.Path.Root
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
createIfNotExists(projectApiPath, apiWrapper)
createIfNotExists(projectDmnPath, dmnWrapper)
createIfNotExists(projectSimulationPath, simulationWrapper)
createIfNotExists(projectWorkerPath, workerWrapper)
createIfNotExists(projectWorkerHandlerPath, workerHandlerWrapper)
createIfNotExists(projectWorkerContextPath, workerContextWrapper)
createIfNotExists(projectWorkerPasswordPath, workerPasswordWrapper)
createIfNotExists(projectWorkerRestApiPath, workerRestApiWrapper)
createIfNotExists(projectHelperPath, helperWrapper)

private lazy val companyName = config.companyName
Expand All @@ -19,7 +22,10 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
private lazy val projectApiPath = ModuleConfig.apiModule.srcPath / "CompanyApiCreator.scala"
private lazy val projectDmnPath = ModuleConfig.dmnModule.srcPath / "CompanyDmnTester.scala"
private lazy val projectSimulationPath = ModuleConfig.simulationModule.srcPath / "CompanySimulation.scala"
private lazy val projectWorkerPath = ModuleConfig.workerModule.srcPath / "CompanyWorkerHandler.scala"
private lazy val projectWorkerHandlerPath = ModuleConfig.workerModule.srcPath / "CompanyWorkerHandler.scala"
private lazy val projectWorkerContextPath = ModuleConfig.workerModule.srcPath / "CompanyEngineContext.scala"
private lazy val projectWorkerPasswordPath = ModuleConfig.workerModule.srcPath / "CompanyPasswordFlow.scala"
private lazy val projectWorkerRestApiPath = ModuleConfig.workerModule.srcPath / "CompanyRestApiClient.scala"
private lazy val projectHelperPath = ModuleConfig.helperModule.srcPath / "CompanyDevHelper.scala"

private lazy val bpmnWrapper =
Expand Down Expand Up @@ -87,12 +93,10 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
|end CompanySimulation
|""".stripMargin

private lazy val workerWrapper =
private lazy val workerHandlerWrapper =
s"""package $companyName.camundala.worker
|
|import camundala.camunda7.worker.C7WorkerHandler
|import camundala.worker.*
|
|import camundala.camunda7.worker.C7WorkerHandler |
|import scala.reflect.ClassTag
|
|/**
Expand All @@ -108,10 +112,6 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
| InConfig <: Product: InOutCodec
|] extends CompanyWorkerHandler, InitWorkerDsl[In, Out, InitIn, InConfig]
|
|trait CompanyValidationWorkerDsl[
| In <: Product: InOutCodec
|] extends CompanyWorkerHandler, ValidationWorkerDsl[In]
|
|trait CompanyCustomWorkerDsl[
| In <: Product: InOutCodec,
| Out <: Product: InOutCodec
Expand All @@ -125,6 +125,70 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
|] extends CompanyWorkerHandler, ServiceWorkerDsl[In, Out, ServiceIn, ServiceOut]
|""".stripMargin

private lazy val workerContextWrapper =
s"""package $companyName.camundala.worker
|
|import camundala.camunda7.worker.Camunda7Context
|import scala.compiletime.uninitialized
|import scala.reflect.ClassTag
|
|@SpringConfiguration
|class CompanyEngineContext extends Camunda7Context:
|
| @Autowired()
| var restApiClient: CompanyRestApiClient = uninitialized
|
| override def sendRequest[ServiceIn: Encoder, ServiceOut: Decoder: ClassTag](
| request: RunnableRequest[ServiceIn]
| ): SendRequestType[ServiceOut] =
| restApiClient.sendRequest(request)
|
|end CompanyEngineContext
|""".stripMargin

private lazy val workerPasswordWrapper =
s"""package $companyName.camundala.worker
|
|import camundala.camunda7.worker.oauth.OAuthPasswordFlow
|
|trait CompanyPasswordFlow extends OAuthPasswordFlow:
|
| lazy val fssoRealm: String = sys.env.getOrElse("FSSO_REALM", "myRealm")
| // default is a local keycloak server on colime docker environment
| lazy val fssoBaseUrl = sys.env.getOrElse("FSSO_BASE_URL", s"http://host.lima.internal:8090")
|
| override lazy val client_id = sys.env.getOrElse("FSSO_CLIENT_NAME", "myClientKey")
| override lazy val client_secret = sys.env.getOrElse("FSSO_CLIENT_SECRET", "myClientSecret")
| override lazy val scope = sys.env.getOrElse("FSSO_SCOPE", "myScope")
| override lazy val username = sys.env.getOrElse("FSSO_TECHUSER_NAME", "myTechUser")
| override lazy val password = sys.env.getOrElse("FSSO_TECHUSER_PASSWORD", "myTechUserPassword")
|
|end CompanyPasswordFlow
|""".stripMargin

private lazy val workerRestApiWrapper =
s"""package $companyName.camundala.worker
|
|import camundala.camunda7.worker.RestApiClient
|import camundala.worker.CamundalaWorkerError.*
|import sttp.client3.*
|
|@SpringConfiguration
|class CompanyRestApiClient extends RestApiClient, CompanyPasswordFlow:
|
| override protected def auth(
| request: Request[Either[String, String], Any]
| )(using
| context: EngineRunContext
| ): Either[ServiceAuthError, Request[Either[String, String], Any]] =
| tokenService.adminToken()
| .map:
| request.addToken
| end auth
|
|end CompanyRestApiClient
|""".stripMargin

private lazy val helperWrapper =
s"""package $companyName.camundala.helper
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ case class WorkerGenerator()(using config: DevConfig):
|@Component("${config.projectClassName}$objName")
|@ConfigurationPropertiesScan
|@ComponentScan(basePackages = Array(
| "camundala.camunda7.worker.oauth",
| "$companyName.camundala.worker",
| "${config.projectPackage}.worker",
| ${
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ trait RestApiClient:
val runtimeClass = implicitly[ClassTag[ServiceOut]].runtimeClass
runtimeClass == classOf[NoOutput]

extension (request: Request[Either[String, String], Any])

def addToken(token: String): RequestT[Identity, Either[String, String], Any] =
val tokenHeader = if token.startsWith("Bearer") then token else s"Bearer $token"
request.header("Authorization", tokenHeader)

end extension
end RestApiClient

object DefaultRestApiClient extends RestApiClient
Loading

0 comments on commit 1c7b7e5

Please sign in to comment.