Skip to content

Commit

Permalink
feat(repo): support passing middleware
Browse files Browse the repository at this point in the history
fixes #261
  • Loading branch information
jwulf committed Sep 27, 2024
1 parent 3055734 commit 1b7715e
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 26 deletions.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,31 @@ Here is an example of turning on debugging for the OAuth and Operate components:
DEBUG=camunda:oauth,camunda:operate node app.js
```

## Process Variable Typing

Process variables - the `variables` of Zeebe messages, jobs, and process instance creation requests and responses - are stored in the broker as key:value pairs. They are transported as a JSON string. The SDK parses the JSON string into a JavaScript object.

Various Zeebe methods accept DTO classes for variable input and output. These DTO classes are used to provide design-time type information on the `variables` object. They are also used to safely decode 64-bit integer values that cannot be accurately represented by the JavaScript `number` type.

To create a DTO to represent the expected shape and type of the `variables` object, extend the `LosslessDto` class:

```typescript
class myVariableDTO extends LosslessDto {
firstName!: string
lastName!: string
age!: number
optionalValue?: number
@Int64String
veryBigInteger?: string
constructor(data: Partial<myVariableDTO>) {
super(data)
}
}
```

## Typing of Zeebe worker variables

The variable payload in a Zeebe worker task handler is available as an object `job.variables`. By default, this is of type `any`.
The variable payload in a Zeebe worker task handler is available as an object `job.variables`. By default, this is of type `any` for the gRPC API, and `unknown` for the REST API.

The `ZBClient.createWorker()` method accepts an `inputVariableDto` to control the parsing of number values and provide design-time type information. Passing an `inputVariableDto` class to a Zeebe worker is optional. If a DTO class is passed to the Zeebe worker, it is used for two purposes:

Expand Down
3 changes: 2 additions & 1 deletion docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# CAMUNDA_CONNECTORS_VERSION=0.23.2
CAMUNDA_CONNECTORS_VERSION=8.5.0
CAMUNDA_OPTIMIZE_VERSION=8.5.0
CAMUNDA_PLATFORM_VERSION=8.5.0
CAMUNDA_PLATFORM_VERSION=8.6.0
CAMUNDA_ZEEBE_VERSION=SNAPSHOT
CAMUNDA_WEB_MODELER_VERSION=8.5.0
ELASTIC_VERSION=8.9.0
KEYCLOAK_SERVER_VERSION=22.0.3
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose-multitenancy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

services:
zeebe: # https://docs.camunda.io/docs/self-managed/platform-deployment/docker/#zeebe
image: camunda/zeebe:${CAMUNDA_PLATFORM_VERSION}
image: camunda/zeebe:${CAMUNDA_ZEEBE_VERSION}
container_name: zeebe
ports:
- "26500:26500"
Expand Down
10 changes: 5 additions & 5 deletions src/__tests__/c8/rest/createProcess.rest.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path'

import { CamundaRestClient } from '../../../c8/lib/CamundaRestClient'
import { LosslessDto } from '../../../lib'
import { createDtoInstance, LosslessDto } from '../../../lib'

jest.setTimeout(17000)

Expand Down Expand Up @@ -52,7 +52,7 @@ test('Can create a process with a lossless Dto', (done) => {
restClient
.createProcessInstance({
processDefinitionKey,
variables: new myVariableDto({ someNumberField: 8 }),
variables: createDtoInstance(myVariableDto, { someNumberField: 8 }),
})
.then((res) => {
expect(res.processDefinitionKey).toEqual(processDefinitionKey)
Expand All @@ -61,7 +61,7 @@ test('Can create a process with a lossless Dto', (done) => {
})

test('Can create a process and get the result', (done) => {
const variables = new myVariableDto({ someNumberField: 8 })
const variables = createDtoInstance(myVariableDto, { someNumberField: 8 })
restClient
.createProcessInstanceWithResult({
processDefinitionKey,
Expand All @@ -79,7 +79,7 @@ test('Can create a process and get the result', (done) => {
restClient
.createProcessInstanceWithResult({
processDefinitionKey,
variables: new myVariableDto({ someNumberField: 9 }),
variables: createDtoInstance(myVariableDto, { someNumberField: 9 }),
})
.then((res) => {
expect(res.processDefinitionKey).toEqual(processDefinitionKey)
Expand All @@ -98,7 +98,7 @@ test('What happens if we time out?', async () => {
await expect(
restClient.createProcessInstanceWithResult({
bpmnProcessId,
variables: new myVariableDto({ someNumberField: 9 }),
variables: createDtoInstance(myVariableDto, { someNumberField: 9 }),
requestTimeout: 20000,
})
).rejects.toThrow('504')
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/c8/rest/migrateProcess.rest.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path'

import { CamundaJobWorker } from 'c8/lib/C8JobWorker'
import { CamundaJobWorker } from 'c8/lib/CamundaJobWorker'

import { CamundaRestClient } from '../../../c8/lib/CamundaRestClient'
import { LosslessDto } from '../../../lib'
Expand Down
1 change: 1 addition & 0 deletions src/admin/lib/AdminApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class AdminApiClient {
),
],
beforeError: [gotBeforeErrorHook],
beforeRequest: config.middleware ?? [],
},
})
)
Expand Down
48 changes: 32 additions & 16 deletions src/c8/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,60 +59,72 @@ export class Camunda8 {
this.log = getLogger(config)
}

public getOperateApiClient(): OperateApiClient {
public getOperateApiClient(
config: Camunda8ClientConfiguration = {}
): OperateApiClient {
if (!this.operateApiClient) {
this.operateApiClient = new OperateApiClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
return this.operateApiClient
}

public getAdminApiClient(): AdminApiClient {
public getAdminApiClient(
config: Camunda8ClientConfiguration = {}
): AdminApiClient {
if (!this.adminApiClient) {
this.adminApiClient = new AdminApiClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
return this.adminApiClient
}

public getModelerApiClient(): ModelerApiClient {
public getModelerApiClient(
config: Camunda8ClientConfiguration = {}
): ModelerApiClient {
if (!this.modelerApiClient) {
this.modelerApiClient = new ModelerApiClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
return this.modelerApiClient
}

public getOptimizeApiClient(): OptimizeApiClient {
public getOptimizeApiClient(
config: Camunda8ClientConfiguration = {}
): OptimizeApiClient {
if (!this.optimizeApiClient) {
this.optimizeApiClient = new OptimizeApiClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
return this.optimizeApiClient
}

public getTasklistApiClient(): TasklistApiClient {
public getTasklistApiClient(
config: Camunda8ClientConfiguration = {}
): TasklistApiClient {
if (!this.tasklistApiClient) {
this.tasklistApiClient = new TasklistApiClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
return this.tasklistApiClient
}

public getZeebeGrpcApiClient(): ZeebeGrpcClient {
public getZeebeGrpcApiClient(
config: Camunda8ClientConfiguration = {}
): ZeebeGrpcClient {
if (!this.zeebeGrpcApiClient) {
this.zeebeGrpcApiClient = new ZeebeGrpcClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
Expand All @@ -122,20 +134,24 @@ export class Camunda8 {
/**
* @deprecated from 8.6.0. Please use getCamundaRestClient() instead.
*/
public getZeebeRestClient(): ZeebeRestClient {
public getZeebeRestClient(
config: Camunda8ClientConfiguration = {}
): ZeebeRestClient {
if (!this.zeebeRestClient) {
this.zeebeRestClient = new ZeebeRestClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
return this.zeebeRestClient
}

public getCamundaRestClient(): CamundaRestClient {
public getCamundaRestClient(
config: Camunda8ClientConfiguration = {}
): CamundaRestClient {
if (!this.camundaRestClient) {
this.camundaRestClient = new CamundaRestClient({
config: this.configuration,
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
})
}
Expand Down
1 change: 1 addition & 0 deletions src/c8/lib/CamundaRestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export class CamundaRestClient {
this.log.debug(`${method} ${path}`)
this.log.silly(body)
},
...(config.middleware ?? []),
],
},
})
Expand Down
5 changes: 4 additions & 1 deletion src/lib/Configuration.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BeforeRequestHook } from 'got'
import mergeWith from 'lodash.mergewith'
import { createEnv } from 'neon-env'
import winston from 'winston'
Expand Down Expand Up @@ -433,7 +434,9 @@ export class CamundaEnvironmentConfigurator {

export type CamundaPlatform8Configuration = ReturnType<
typeof CamundaEnvironmentConfigurator.ENV
>
> & {
middleware?: BeforeRequestHook[]
}

export type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]
Expand Down
1 change: 1 addition & 0 deletions src/modeler/lib/ModelerAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class ModelerApiClient {
),
],
beforeError: [gotBeforeErrorHook],
beforeRequest: config.middleware ?? [],
},
})
)
Expand Down
1 change: 1 addition & 0 deletions src/operate/lib/OperateApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class OperateApiClient {
),
],
beforeError: [gotBeforeErrorHook],
beforeRequest: config.middleware ?? [],
},
})
)
Expand Down
1 change: 1 addition & 0 deletions src/optimize/lib/OptimizeApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class OptimizeApiClient {
),
],
beforeError: [gotBeforeErrorHook],
beforeRequest: config.middleware ?? [],
},
})
)
Expand Down
1 change: 1 addition & 0 deletions src/tasklist/lib/TasklistApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export class TasklistApiClient {
),
],
beforeError: [gotBeforeErrorHook],
beforeRequest: config.middleware ?? [],
},
})
)
Expand Down

0 comments on commit 1b7715e

Please sign in to comment.