Skip to content

Commit

Permalink
accept options when deleting from storaga adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
paed01 committed Dec 29, 2024
1 parent 835aaf5 commit 12b3d57
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 233 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

## [0.15.1] - 2024-12-28

- accept options when deleting from storaga adapter

## [0.15.0] - 2024-12-27

- add ability to pass custom resume engine request handler function
Expand Down
3 changes: 2 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,13 @@ Fetch entry by key.
- `options`: optional object with options
- `exclude`: optional list of fields to exclude

### `async delete(type, key)`
### `async delete(type, key[, options])`

Delete entry by key.

- `type`: string, storage type, `deployment`, `file`, or `state`
- `key`: string, storage key
- `options`: optional object with options

### `async query(type, qs[, options])`

Expand Down
2 changes: 1 addition & 1 deletion example/processes/task.bpmn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0aa0qjx" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.30.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.19.0">
<bpmn:process id="Process_0xa818o" isExecutable="true">
<bpmn:process id="Process_0xa818o" isExecutable="true" camunda:historyTimeToLive="PT30S">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1onlbrs</bpmn:outgoing>
</bpmn:startEvent>
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bpmn-middleware",
"version": "0.15.0",
"version": "0.15.1",
"description": "BPMN engine express middleware",
"type": "module",
"main": "./dist/main.cjs",
Expand Down Expand Up @@ -43,7 +43,7 @@
},
"homepage": "https://github.com/zerodep/bpmn-middleware#readme",
"devDependencies": {
"@onify/flow-extensions": "^8.3.0",
"@onify/flow-extensions": "^9.0.0",
"@rollup/plugin-commonjs": "^28.0.0",
"@types/bpmn-moddle": "^5.1.11",
"@types/debug": "^4.1.12",
Expand Down Expand Up @@ -72,10 +72,11 @@
"multer": "^1.4.5-lts.1"
},
"peerDependencies": {
"bpmn-engine": ">=15",
"bpmn-elements": "*",
"bpmn-engine": ">=15",
"debug": "*",
"express": ">=4",
"moddle-context-serializer": "*",
"smqp": "*"
},
"files": [
Expand Down
133 changes: 133 additions & 0 deletions test/features/memory-adapter-feature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import request from 'supertest';
import { LRUCache } from 'lru-cache';

import { getAppWithExtensions, createDeployment, waitForProcess } from '../helpers/test-helpers.js';
import { MemoryAdapter } from '../../src/index.js';

Feature('memory adapter', () => {
Scenario('built in memory adapter', () => {
let app1, app2, storage;
after(() => {
return Promise.all([
request(app1).delete('/rest/internal/stop').expect(204),
request(app2).delete('/rest/internal/stop').expect(204),
]);
});

Given('two parallel app instances with a shared adapter storage', () => {
storage = new LRUCache({ max: 100 });
const adapter1 = new MemoryAdapter(storage);
const adapter2 = new MemoryAdapter(storage);

app1 = getAppWithExtensions({ adapter: adapter1 });
app2 = getAppWithExtensions({ adapter: adapter2 });
});

And('a process with a user task with a non-interrupting bound timeout', () => {
return createDeployment(
app2,
'memory-adapter',
`<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<process id="bp" isExecutable="true">
<userTask id="task" />
<boundaryEvent id="bound-timer" attachedToRef="task" cancelActivity="false">
<timerEventDefinition>
<timeDuration xsi:type="tFormalExpression">PT10S</timeDuration>
</timerEventDefinition>
</boundaryEvent>
</process>
</definitions>`
);
});

let response, bp;
When('process is started', async () => {
response = await request(app1).post('/rest/process-definition/memory-adapter/start').expect(201);

bp = response.body;
});

Then('process status is running timer', async () => {
response = await request(app2).get(`/rest/status/${bp.id}`);

expect(response.statusCode, response.text).to.equal(200);
expect(response.body).to.have.property('state', 'running');
expect(response.body).to.have.property('activityStatus', 'timer');
expect(response.body).to.have.property('expireAt').that.is.ok;
});

Given('process run is stopped', () => {
return request(app1).delete(`/rest/internal/stop/${bp.id}`).expect(204);
});

When('process status is fetched', async () => {
response = await request(app2).get(`/rest/status/${bp.id}`);
});

Then('status is still running', () => {
expect(response.statusCode, response.text).to.equal(200);
expect(response.body).to.have.property('state', 'running');
expect(response.body).to.have.property('activityStatus', 'timer');
expect(response.body).to.have.property('expireAt').that.is.ok;
});

let end;
When('process user task is signaled', () => {
end = waitForProcess(app2, bp.id).end();
return request(app2).post(`/rest/signal/${bp.id}`).send({ id: 'task' }).expect(200);
});

Then('run completes', () => {
return end;
});

And('first app also has the completed process', async () => {
response = await request(app1).get(`/rest/status/${bp.id}`);

expect(response.statusCode, response.text).to.equal(200);
expect(response.body).to.have.property('state', 'idle');
});

When('second app signals the completed process', async () => {
response = await request(app2).post(`/rest/signal/${bp.id}`).send({ id: 'task' });
});

Then('bad request is returned with completed message', () => {
expect(response.statusCode, response.text).to.equal(400);
expect(response.body)
.to.have.property('message')
.that.match(/completed/i);
});

When('first app attempts to signal the completed process', async () => {
response = await request(app2).post(`/rest/signal/${bp.id}`).send({ id: 'task' });
});

Then('bad request is returned with completed message', () => {
expect(response.statusCode, response.text).to.equal(400);
expect(response.body)
.to.have.property('message')
.that.match(/completed/i);
});

Given('the state is purged', () => {
storage.delete(`state:${bp.id}`);
});

When('first app attempts to signal the completed process', async () => {
response = await request(app2).post(`/rest/signal/${bp.id}`).send({ id: 'task' });
});

Then('not found is returned', () => {
expect(response.statusCode, response.text).to.equal(404);
});

When('process is ran again', async () => {
response = await request(app1).post('/rest/process-definition/memory-adapter/start').expect(201);

bp = response.body;
});
});
});
Loading

0 comments on commit 12b3d57

Please sign in to comment.