Skip to content

Commit e748408

Browse files
Merge pull request #150 from XavierGeerinck/master
feat(state): Add State Query API
2 parents c005d80 + ce8d8cf commit e748408

File tree

13 files changed

+194
-278
lines changed

13 files changed

+194
-278
lines changed

documentation/development.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Tests are written per protocol layer: http or grpc. This is done because Dapr re
3636
# Ports: 1883 = TCP MQTT Port | 8081 = HTTP API | 8083 = MQTT/SSL Port | 8883 = MQTT/Websocket/SSL Port | 8084 = MQTT/Websocket Port | 18083 = Dashboard
3737
docker run -d --rm --name emqx -p 1883:1883 -p 8081:8081 -p 8083:8083 -p 8883:8883 -p 8084:8084 -p 18083:18083 emqx/emqx
3838

39+
# Start MongoDB for State Query
40+
docker run -d --rm --name mongodb -p 27017:27017 mongo
41+
3942
# Run Unit Tests
4043
npm run test:unit:main
4144
npm run test:unit:actors

src/implementation/Client/GRPCClient/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export default class GRPCClientState implements IClientState {
197197

198198
// https://docs.dapr.io/reference/api/state_api/#response-body
199199
// map the res from gRPC
200-
let resMapped: StateQueryResponseType = {
200+
const resMapped: StateQueryResponseType = {
201201
results: res.getResultsList().map((i) => ({
202202
key: i.getKey(),
203203
data: i.getData(),

src/implementation/Client/HTTPClient/HTTPClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export default class HTTPClient implements IClient {
7373
this.httpsAgent.destroy();
7474
}
7575

76-
async executeWithApiVersion(apiVersion: string = "v1.0", url: string, params: any = {}): Promise<object | string> {
76+
async executeWithApiVersion(apiVersion = "v1.0", url: string, params: any = {}): Promise<object | string> {
7777
const newClientUrl = this.clientUrl.replace("v1.0", apiVersion);
7878
return await this.execute(`${newClientUrl}${url}`, params);
7979
}

src/implementation/Client/HTTPClient/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export default class HTTPClientState implements IClientState {
7171
"Content-Type": "application/json"
7272
},
7373
body: JSON.stringify({
74-
query
74+
...query
7575
})
7676
});
7777

src/implementation/Server/DaprServer.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ export default class DaprServer {
9999
await this.daprServer.stop();
100100
}
101101

102-
async stopServer(): Promise<void> {
103-
await this.daprServer.stopServer();
104-
}
105-
106102
getDaprClient(): IServer {
107103
return this.daprServer;
108104
}

src/implementation/Server/GRPCServer/GRPCServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export default class GRPCServer implements IServer {
7777
// if we are using actors we will change this to 4s to let the placement tables update
7878
let isHealthy = false;
7979
let isHealthyRetryCount = 0;
80-
let isHealthyMaxRetryCount = 60; // 1s startup delay and we try max for 60s
80+
const isHealthyMaxRetryCount = 60; // 1s startup delay and we try max for 60s
8181

8282
console.log(`[Dapr-JS] Letting Dapr pick-up the server (Maximum 60s wait time)`);
8383
while (!isHealthy) {

src/implementation/Server/HTTPServer/HTTPServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export default class HTTPServer implements IServer {
104104
// if we are using actors we will change this to 4s to let the placement tables update
105105
let isHealthy = false;
106106
let isHealthyRetryCount = 0;
107-
let isHealthyMaxRetryCount = 60; // 1s startup delay and we try max for 60s
107+
const isHealthyMaxRetryCount = 60; // 1s startup delay and we try max for 60s
108108

109109
console.log(`[Dapr-JS] Letting Dapr pick-up the server (Maximum 60s wait time)`);
110110
while (!isHealthy) {

src/types/StateQuery.type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Enumerable } from "./Enumerable.type"
33
export type StateQueryType = {
44
filter: StateQueryFilter;
55
sort: StateQuerySort[];
6-
pagination: StateQueryPagination;
6+
page: StateQueryPagination;
77
}
88

99
type StateQuerySort = {

test/components/state-mongodb.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: dapr.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: state-mongodb
5+
spec:
6+
type: state.mongodb
7+
version: v1
8+
metadata:
9+
- name: host
10+
value: localhost:27017

test/e2e/main.grpc.test.ts

Lines changed: 36 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -205,165 +205,52 @@ describe('grpc/main', () => {
205205
expect(res).toEqual('');
206206
});
207207

208-
describe('state', () => {
209-
it('should be able to save the state', async () => {
210-
await client.state.save('state-redis', [
211-
{
212-
key: 'key-1',
213-
value: 'value-1',
214-
},
215-
{
216-
key: 'key-2',
217-
value: 2,
218-
},
219-
{
220-
key: 'key-3',
221-
value: true,
222-
},
223-
{
224-
key: 'key-4',
225-
value: {
226-
nested: {
227-
str: 'string',
228-
num: 123,
229-
},
230-
},
231-
},
232-
]);
233-
234-
const res = await Promise.all([
235-
client.state.get('state-redis', 'key-1'),
236-
client.state.get('state-redis', 'key-2'),
237-
client.state.get('state-redis', 'key-3'),
238-
client.state.get('state-redis', 'key-4'),
239-
]);
240-
241-
expect(res).toEqual([
242-
'value-1',
243-
2,
244-
true,
245-
{
246-
nested: {
247-
str: 'string',
248-
num: 123,
249-
},
250-
},
251-
]);
252-
});
253-
254-
it('should be able to get the state in bulk', async () => {
255-
await client.state.save('state-redis', [
256-
{
257-
key: 'key-1',
258-
value: 'value-1',
259-
},
260-
{
261-
key: 'key-2',
262-
value: 2,
263-
},
264-
{
265-
key: 'key-3',
266-
value: true,
267-
},
268-
{
269-
key: 'key-4',
270-
value: {
271-
nested: {
272-
str: 'string',
273-
num: 123,
274-
},
275-
},
276-
},
277-
]);
278-
279-
const res = await client.state.getBulk('state-redis', ['key-3', 'key-2', 'key-1', 'key-4']);
280-
281-
expect(res).toEqual(
282-
expect.arrayContaining([
283-
expect.objectContaining({ key: 'key-1', data: 'value-1' }),
284-
expect.objectContaining({ key: 'key-2', data: 2 }),
285-
expect.objectContaining({ key: 'key-3', data: true }),
286-
expect.objectContaining({
287-
key: 'key-4',
288-
data: {
289-
nested: {
290-
str: 'string',
291-
num: 123,
292-
},
293-
},
294-
}),
295-
]),
296-
);
297-
});
298-
299-
it('should be able to delete a key from the state store', async () => {
300-
await client.state.save('state-redis', [
301-
{
208+
it('should be able to perform a transaction that replaces a key and deletes another', async () => {
209+
await client.state.transaction('state-redis', [
210+
{
211+
operation: 'upsert',
212+
request: {
302213
key: 'key-1',
303-
value: 'value-1',
304-
},
305-
{
306-
key: 'key-2',
307-
value: 'value-2',
214+
value: 'my-new-data-1',
308215
},
309-
{
216+
},
217+
{
218+
operation: 'delete',
219+
request: {
310220
key: 'key-3',
311-
value: 'value-3',
312221
},
313-
]);
222+
},
223+
]);
314224

315-
await client.state.delete('state-redis', 'key-2');
316-
const res = await client.state.get('state-redis', 'key-2');
317-
expect(res).toEqual('');
318-
});
225+
const resTransactionDelete = await client.state.get('state-redis', 'key-3');
226+
const resTransactionUpsert = await client.state.get('state-redis', 'key-1');
227+
expect(resTransactionDelete).toEqual('');
228+
expect(resTransactionUpsert).toEqual('my-new-data-1');
229+
});
319230

320-
it('should be able to perform a transaction that replaces a key and deletes another', async () => {
321-
await client.state.transaction('state-redis', [
322-
{
323-
operation: 'upsert',
324-
request: {
325-
key: 'key-1',
326-
value: 'my-new-data-1',
327-
},
231+
it('should be able to perform a transaction with metadata', async () => {
232+
await client.state.transaction('state-redis', [
233+
{
234+
operation: 'upsert',
235+
request: {
236+
key: 'key-with-metadata-1',
237+
value: 'my-new-data-with-metadata-1',
328238
},
329-
{
330-
operation: 'delete',
331-
request: {
332-
key: 'key-3',
333-
},
239+
},
240+
{
241+
operation: 'delete',
242+
request: {
243+
key: 'key-with-metadata-2',
334244
},
335-
]);
336-
337-
const resTransactionDelete = await client.state.get('state-redis', 'key-3');
338-
const resTransactionUpsert = await client.state.get('state-redis', 'key-1');
339-
expect(resTransactionDelete).toEqual('');
340-
expect(resTransactionUpsert).toEqual('my-new-data-1');
245+
},
246+
], {
247+
trace_id: 'mock trace id here',
341248
});
342249

343-
it('should be able to perform a transaction with metadata', async () => {
344-
await client.state.transaction('state-redis', [
345-
{
346-
operation: 'upsert',
347-
request: {
348-
key: 'key-with-metadata-1',
349-
value: 'my-new-data-with-metadata-1',
350-
},
351-
},
352-
{
353-
operation: 'delete',
354-
request: {
355-
key: 'key-with-metadata-2',
356-
},
357-
},
358-
], {
359-
trace_id: 'mock trace id here',
360-
});
361-
362-
const resTransactionDelete = await client.state.get('state-redis', 'key-with-metadata-2');
363-
const resTransactionUpsert = await client.state.get('state-redis', 'key-with-metadata-1');
364-
expect(resTransactionDelete).toEqual('');
365-
expect(resTransactionUpsert).toEqual('my-new-data-with-metadata-1');
366-
});
250+
const resTransactionDelete = await client.state.get('state-redis', 'key-with-metadata-2');
251+
const resTransactionUpsert = await client.state.get('state-redis', 'key-with-metadata-1');
252+
expect(resTransactionDelete).toEqual('');
253+
expect(resTransactionUpsert).toEqual('my-new-data-with-metadata-1');
367254
});
368255
});
369256

0 commit comments

Comments
 (0)