Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions commonjs/generated.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const pkgs = [
'../out/wechaty/puppet/base_pb.js',
'../out/wechaty/puppet/contact_pb.js',
'../out/wechaty/puppet/download-upload_pb.js',
'../out/wechaty/puppet/event_pb.js',
'../out/wechaty/puppet/file-box_pb.js',
'../out/wechaty/puppet/friendship_pb.js',
Expand All @@ -14,6 +15,9 @@ const pkgs = [
'../out/wechaty/puppet/tag_pb.js',
'../out/wechaty/puppet/url-link_pb.js',

'../out/wechaty/health_grpc_pb.js',
'../out/wechaty/health_pb.js',

'../out/wechaty/puppet_grpc_pb.js',
'../out/wechaty/puppet_pb.js',
]
Expand Down
6 changes: 5 additions & 1 deletion commonjs/generated.cjs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
* const puppet = pkg['puppet']
* ```
*/
export * from '../out/wechaty/puppet/base_pb'
export * from '../out/wechaty/puppet/base_pb.js'
export * from '../out/wechaty/puppet/contact_pb.js'
export * from '../out/wechaty/puppet/download-upload_pb.js'
export * from '../out/wechaty/puppet/event_pb.js'
export * from '../out/wechaty/puppet/file-box_pb.js'
export * from '../out/wechaty/puppet/friendship_pb.js'
Expand All @@ -38,3 +39,6 @@ export * from '../out/wechaty/puppet/url-link_pb.js'

export * from '../out/wechaty/puppet_grpc_pb.js'
export * from '../out/wechaty/puppet_pb.js'

export * from '../out/wechaty/health_grpc_pb.js'
export * from '../out/wechaty/health_pb.js'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wechaty-grpc",
"version": "0.31.3",
"version": "0.31.5",
"description": "gRPC for Wechaty",
"type": "module",
"exports": {
Expand Down
33 changes: 33 additions & 0 deletions proto/wechaty/health.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* https://github.com/grpc/grpc/blob/master/doc/health-checking.md
*
* Huan(202110): is there an already existing proto file for health checking?
* (instead of copy/paste at here)
*/
syntax = "proto3";

package wechaty.puppet;

option csharp_namespace = "github.wechaty.grpc.puppet";
option go_package = "github.com/wechaty/go-grpc/wechaty";
option java_package = "io.github.wechaty.grpc";

enum ServingStatus {
SERVING_STATUS_UNSPECIFIC = 0;
SERVING_STATUS_SERVING = 1;
SERVING_STATUS_NOT_SERVING = 2;
SERVING_STATUS_SERVICE_UNKNOWN = 3; // Used only by the Watch method.
}

message HealthCheckRequest {
string service = 1;
}

message HealthCheckResponse {
ServingStatus status = 1;
}

service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}
18 changes: 17 additions & 1 deletion proto/wechaty/puppet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
*
*/
syntax = "proto3";
package wechaty;
package wechaty.puppet;

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

import "wechaty/puppet/base.proto";
import "wechaty/puppet/contact.proto";
import "wechaty/puppet/download-upload.proto";
import "wechaty/puppet/event.proto";
import "wechaty/puppet/friendship.proto";
import "wechaty/puppet/message.proto";
Expand Down Expand Up @@ -499,4 +500,19 @@ service Puppet {
};
}

/**
* File/Blob download & upload
*/
rpc Download (puppet.DownloadRequest) returns (stream puppet.DownloadResponse) {
option (google.api.http) = {
get: "/download/{id}"
};
}
rpc Upload (stream puppet.UploadRequest) returns (puppet.UploadResponse) {
option (google.api.http) = {
post: "/upload"
body: "*"
};
}

}
19 changes: 19 additions & 0 deletions proto/wechaty/puppet/download-upload.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
syntax = "proto3";
package wechaty.puppet;

option go_package="github.com/wechaty/go-grpc/wechaty/puppet";
option csharp_namespace = "github.wechaty.grpc.puppet";

message UploadRequest {
bytes chunk = 1;
}
message UploadResponse {
string id = 1;
}

message DownloadRequest {
string id = 1;
}
message DownloadResponse {
bytes chunk = 1;
}
12 changes: 8 additions & 4 deletions proto/wechaty/puppet/file-box.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ option go_package="github.com/wechaty/go-grpc/wechaty/puppet";
option csharp_namespace = "github.wechaty.grpc.puppet";

message FileBoxChunk {
oneof payload {
bytes data = 1;
string name = 2;
}
/**
* Huan(202110): `oneof xxx {}` seems equal with `optional`?
* to be confirmed.
*/
// oneof payload {
optional bytes data = 1;
optional string name = 2;
// }
}
102 changes: 102 additions & 0 deletions tests/health-check.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env -S node --no-warnings --loader ts-node/esm

import { test } from 'tstest'

import { promisify } from 'util'

import {
grpc,
puppet,
} from '../src/mod.js'

test('HealthCheck protocol buffer', async t => {
const request = new puppet.HealthCheckRequest()
const response = new puppet.HealthCheckResponse()
response.setStatus(puppet.ServingStatus.SERVING_STATUS_SERVICE_UNKNOWN)
await t.ok(request && response, 'should export HealCheck protobuf')
})

test('health check smoke testing', async t => {
const ENDPOINT = 'localhost:18788'

/**
* Create Server
*/
const testServer = getTestServer()

const server = new grpc.Server()
server.addService(
puppet.HealthService,
testServer,
)
await promisify(
server.bindAsync
.bind(server)
)(
ENDPOINT,
grpc.ServerCredentials.createInsecure(),
)
server.start()

/**
* Create Client
*/
const client = new puppet.HealthClient(
ENDPOINT,
grpc.credentials.createInsecure()
)

const request = new puppet.HealthCheckRequest()
const response = await promisify(
client.check
.bind(client)
)(request) as any

t.equal(response.getStatus(), puppet.ServingStatus.SERVING_STATUS_SERVING, 'should return SERVING_STATUS_SERVING for check method')

/**
* gRPC: Stream
*/
const eventStream = client.watch(request)

let counter = 0
const future = new Promise<void>((resolve, reject) => {
eventStream
.on('data', (response: puppet.HealthCheckResponse) => {
t.equal(response.getStatus(), puppet.ServingStatus.SERVING_STATUS_SERVING, `should return SERVING_STATUS_SERVING for watch method with counter #${counter}`)
counter++
})
.on('close', resolve)
.on('error', reject)
})

await future
t.equal(counter, 2, 'should return 2 responses')

await new Promise(resolve => server.tryShutdown(resolve))
// server.forceShutdown()
})

function getTestServer () {

const puppetTestServer: puppet.IHealthServer = {
check: (_call, callback) => {
const response = new puppet.HealthCheckResponse()
response.setStatus(puppet.ServingStatus.SERVING_STATUS_SERVING)
callback(null, response)
},
watch: (call) => {
const response1 = new puppet.HealthCheckResponse()
response1.setStatus(puppet.ServingStatus.SERVING_STATUS_SERVING)
call.write(response1)

const response2 = new puppet.HealthCheckResponse()
response2.setStatus(puppet.ServingStatus.SERVING_STATUS_SERVING)
call.write(response2)

call.end()
},
}

return puppetTestServer
}
2 changes: 1 addition & 1 deletion tests/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ test('integration testing', async t => {
* Check Result
*/
await future
t.deepEqual(EVENT_DATA_LIST, DING_DATA_LIST, 'should get ding data back through event stream')
t.same(EVENT_DATA_LIST, DING_DATA_LIST, 'should get ding data back through event stream')

/**
* Close Client & Server
Expand Down
12 changes: 12 additions & 0 deletions tests/puppet-server-impl.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable sort-keys */
import type {
puppet,
} from '../src/mod.js'
Expand Down Expand Up @@ -355,4 +356,15 @@ export const puppetServerImpl: IPuppetServer = {
throw new Error('not implemented.')
},

download: (call) => {
void call
throw new Error('not implemented.')
},

upload: (call, callback) => {
void call
void callback
throw new Error('not implemented.')
},

}