wechaty-puppet-service
Version:
Puppet Service for Wechaty
159 lines • 8.48 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PuppetServer = void 0;
/**
* Wechaty Open Source Software - https://github.com/wechaty
*
* @copyright 2016 Huan LI (李卓桓) <https://github.com/huan>, and
* Wechaty Contributors <https://github.com/wechaty>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const util_1 = __importDefault(require("util"));
const wechaty_puppet_1 = require("wechaty-puppet");
const wechaty_grpc_1 = require("wechaty-grpc");
const file_box_1 = require("file-box");
const config_js_1 = require("../config.js");
const mod_js_1 = require("../auth/mod.js");
const ca_js_1 = require("../auth/ca.js");
const puppet_implementation_js_1 = require("./puppet-implementation.js");
const health_implementation_js_1 = require("./health-implementation.js");
const uuidify_file_box_local_js_1 = require("../file-box-helper/uuidify-file-box-local.js");
class PuppetServer {
options;
grpcServer;
urnRegistry;
constructor(options) {
this.options = options;
wechaty_puppet_1.log.verbose('PuppetServer', 'constructor({endpoint: "%s", puppet: "%s", token: "%s"})', options.endpoint, options.puppet, options.token);
}
version() {
return config_js_1.VERSION;
}
async start() {
wechaty_puppet_1.log.verbose('PuppetServer', 'start()');
if (this.grpcServer) {
throw new Error('grpc server existed!');
}
if (!this.urnRegistry) {
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing FileBox UUID URN Registry ...');
this.urnRegistry = new file_box_1.UniformResourceNameRegistry();
await this.urnRegistry.init();
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing FileBox UUID URN Registry ... done');
}
/**
* Connect FileBox with UUID Manager
*/
const FileBoxUuid = (0, uuidify_file_box_local_js_1.uuidifyFileBoxLocal)(this.urnRegistry);
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing gRPC Server with options "%s"', JSON.stringify(config_js_1.GRPC_OPTIONS));
this.grpcServer = new wechaty_grpc_1.grpc.Server(config_js_1.GRPC_OPTIONS);
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing gRPC Server ... done', JSON.stringify(config_js_1.GRPC_OPTIONS));
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing puppet implementation with FileBoxUuid...');
const puppetImpl = (0, puppet_implementation_js_1.puppetImplementation)(this.options.puppet, FileBoxUuid);
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing puppet implementation with FileBoxUuid... done');
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing authorization with token ...');
const puppetImplAuth = (0, mod_js_1.authImplToken)(this.options.token)(puppetImpl);
this.grpcServer.addService(wechaty_grpc_1.puppet.PuppetService, puppetImplAuth);
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing authorization with token ... done');
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing gRPC health service ...');
const healthImpl = (0, health_implementation_js_1.healthImplementation)(this.options.puppet);
this.grpcServer.addService(wechaty_grpc_1.google.HealthService, healthImpl);
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing gRPC health service ... done');
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing TLS CA ...');
const caCerts = config_js_1.envVars.WECHATY_PUPPET_SERVICE_TLS_CA_CERT();
const caCertBuf = caCerts
? Buffer.from(caCerts)
: null;
const certChain = Buffer.from(config_js_1.envVars.WECHATY_PUPPET_SERVICE_TLS_SERVER_CERT(this.options.tls?.serverCert)
|| ca_js_1.TLS_INSECURE_SERVER_CERT);
const privateKey = Buffer.from(config_js_1.envVars.WECHATY_PUPPET_SERVICE_TLS_SERVER_KEY(this.options.tls?.serverKey)
|| ca_js_1.TLS_INSECURE_SERVER_KEY);
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing TLS CA ... done');
const keyCertPairs = [{
cert_chain: certChain,
private_key: privateKey,
}];
/**
* Huan(202108): for maximum compatible with the non-tls community servers/clients,
* we introduced the WECHATY_PUPPET_SERVICE_NO_TLS_INSECURE_{SERVER,CLIENT} environment variables.
* if it has been set, then we will run under HTTP instead of HTTPS
*/
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing gRPC server credentials ...');
let credential;
if (config_js_1.envVars.WECHATY_PUPPET_SERVICE_NO_TLS_INSECURE_SERVER(this.options.tls?.disable)) {
wechaty_puppet_1.log.warn('PuppetServer', 'start() TLS disabled: INSECURE!');
credential = wechaty_grpc_1.grpc.ServerCredentials.createInsecure();
}
else {
wechaty_puppet_1.log.verbose('PuppetServer', 'start() TLS enabled.');
credential = wechaty_grpc_1.grpc.ServerCredentials.createSsl(caCertBuf, keyCertPairs);
}
wechaty_puppet_1.log.verbose('PuppetServer', 'start() initializing gRPC server credentials ... done');
/***
* Start Grpc Server
*/
wechaty_puppet_1.log.verbose('PuppetServer', 'start() gRPC server starting ...');
const port = await util_1.default.promisify(this.grpcServer.bindAsync
.bind(this.grpcServer))(this.options.endpoint, credential);
if (port === 0) {
throw new Error('grpc server bind fail!');
}
this.grpcServer.start();
wechaty_puppet_1.log.verbose('PuppetServer', 'start() gRPC server starting ... done');
}
async stop() {
wechaty_puppet_1.log.verbose('PuppetServer', 'stop()');
if (this.grpcServer) {
const grpcServer = this.grpcServer;
this.grpcServer = undefined;
wechaty_puppet_1.log.verbose('PuppetServer', 'stop() shuting down gRPC server ...');
// const future = await util.promisify(
// grpcServer.tryShutdown
// .bind(grpcServer),
// )()
try {
await new Promise(resolve => setImmediate(resolve));
grpcServer.forceShutdown();
/**
* Huan(202110) grpc.tryShutdown() never return if client close the connection. #176
* @see https://github.com/wechaty/puppet-service/issues/176
*
* FIXME: even after called `forceShutdown()`, the `tryShutdown()` can not resolved.
* commented out the `await` for now to make it work temporary.
*/
// await future
}
catch (e) {
wechaty_puppet_1.log.warn('PuppetServer', 'stop() gRPC shutdown rejection: %s', e.message);
}
finally {
wechaty_puppet_1.log.verbose('PuppetServer', 'stop() shuting down gRPC server ... done');
}
}
else {
wechaty_puppet_1.log.warn('PuppetServer', 'stop() no grpcServer exist');
}
if (this.urnRegistry) {
wechaty_puppet_1.log.verbose('PuppetServer', 'stop() destory URN Registry ...');
await this.urnRegistry.destroy();
this.urnRegistry = undefined;
wechaty_puppet_1.log.verbose('PuppetServer', 'stop() destory URN Registry ... done');
}
}
}
exports.PuppetServer = PuppetServer;
//# sourceMappingURL=puppet-server.js.map