@kuflow/kuflow-temporal-worker
Version:
Worker library used by KuFlow SDKs and Temporal.
224 lines • 9.45 kB
JavaScript
"use strict";
/**
* The MIT License
* Copyright © 2021-present KuFlow S.L.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.KuFlowTemporalConnection = void 0;
const worker_1 = require("@temporalio/worker");
const worker_2 = require("./encryption/worker");
const kuflow_authorization_token_provider_1 = require("./kuflow-authorization-token-provider");
const kuflow_worker_information_notifier_1 = require("./kuflow-worker-information-notifier");
/**
* Configure a temporal client and worker with KuFlow requirements.
*/
class KuFlowTemporalConnection {
options;
/**
* Get the registered workflow types
*/
get workflowTypes() {
return [...this._workflowTypes];
}
/**
* Get the registered activity types
*/
get activityTypes() {
return [...this._activityTypes];
}
/**
* Get the nativeConnection started
*/
get nativeConnection() {
return this._nativeConnection;
}
/**
* Get the worker started
*/
get worker() {
return this._worker;
}
_workflowTypes = [];
_activityTypes = [];
_nativeConnection;
_worker;
_kuFlowAuthorizationTokenProvider;
_kuflowWorkerInformationNotifier;
static async instance(options) {
return new KuFlowTemporalConnection({ ...options });
}
constructor(options) {
this.options = options;
}
/**
* Eagerly connect to the Temporal server and return a NativeConnection instance
*/
async connect() {
if (this._nativeConnection != null) {
return this._nativeConnection;
}
await this.applyDefaultConfiguration();
const connectionOptions = this.options.temporalio.connection ?? {};
if (connectionOptions.address == null) {
connectionOptions.address = 'engine.kuflow.com:443';
}
this._nativeConnection = await worker_1.NativeConnection.connect(connectionOptions);
// Create a KuFlowAuthorizationTokenProvider
this._kuFlowAuthorizationTokenProvider = kuflow_authorization_token_provider_1.KuFlowAuthorizationTokenProvider.instance({
temporalConnection: this._nativeConnection,
options: this.options,
});
worker_1.Runtime.instance().logger.info('Connection created');
return this._nativeConnection;
}
async applyDefaultConfiguration() {
const authenticationParams = {
type: 'ENGINE_CERTIFICATE',
tenantId: this.options.kuflow.tenantId,
};
const kuFlowRestClient = this.options.kuflow.restClient;
const authentication = await kuFlowRestClient.authenticationOperations.createAuthentication(authenticationParams);
if (authentication.engineCertificate?.tls == null) {
return;
}
if (this.options.temporalio.connection == null) {
this.options.temporalio.connection = {};
}
if (this.options.temporalio.connection.tls == null) {
this.options.temporalio.connection.tls = {
serverRootCACertificate: Buffer.from(authentication.engineCertificate.tls.serverRootCaCertificate),
clientCertPair: {
crt: Buffer.from(authentication.engineCertificate.tls.clientCertificate),
key: Buffer.from(authentication.engineCertificate.tls.clientPrivateKey),
},
};
}
if (this.options.temporalio.worker != null && this.options.temporalio.worker.namespace == null) {
this.options.temporalio.worker.namespace = authentication.engineCertificate.namespace;
}
}
/**
* Create a new Worker. This method initiates a connection to the server and will throw (asynchronously) on connection failure.
*/
async createWorker() {
if (this._worker != null) {
return this._worker;
}
if (this.options.temporalio.worker == null) {
throw new Error('Worker options are required');
}
const connection = await this.connect();
this._worker = await worker_1.Worker.create({
...this.options.temporalio.worker,
connection,
interceptors: {
activity: [worker_2.kuFlowEncryptionActivityInterceptorsFactory],
workflowModules: [require.resolve('./encryption/workflow/kuflow-encryption-workflow-interceptors')],
},
dataConverter: {
payloadConverterPath: require.resolve('./encryption/workflow/kuflow-encryption-workflow-payload-converters'),
payloadCodecs: [
new worker_2.KuflowEncryptionPayloadCodec({
restClient: this.options.kuflow.restClient,
}),
],
},
});
worker_1.Runtime.instance().logger.info('Worker initialized');
return this._worker;
}
/**
* Start the temporal worker configured.
*/
async runWorker() {
worker_1.Runtime.instance().logger.info('Run worker');
const worker = await this.createWorker();
if (worker.options.workflowsPath != null) {
const workflowsPath = worker.options.workflowsPath;
const workflows = (await Promise.resolve(`${workflowsPath}`).then(s => __importStar(require(s))));
this._workflowTypes = Object.keys(workflows).filter(key => typeof workflows[key] === 'function');
}
if (worker.options.activities != null) {
this._activityTypes = Object.keys(worker.options.activities ?? {});
}
// Create a KuflowWorkerInformationNotifier
this._kuflowWorkerInformationNotifier = kuflow_worker_information_notifier_1.KuFlowWorkerInformationNotifier.instance({
workerInformation: {
identity: worker.options.identity,
taskQueue: worker.options.taskQueue,
workflowTypes: this._workflowTypes,
activityTypes: this._activityTypes,
},
options: this.options,
});
await this._kuflowWorkerInformationNotifier.start();
worker_1.Runtime.instance().logger.info('Running worker');
await worker.run();
}
/**
* Shutdown the worker (if is started) and all related objects that need to be closed.
*/
async close() {
if (this._worker != null && this._worker.getState() === 'RUNNING') {
this._worker.shutdown();
this._activityTypes = [];
this._workflowTypes = [];
this._worker = undefined;
}
if (this._nativeConnection != null) {
await this._nativeConnection.close();
this._nativeConnection = undefined;
}
if (this._kuflowWorkerInformationNotifier != null) {
await this._kuflowWorkerInformationNotifier.close();
this._kuflowWorkerInformationNotifier = undefined;
}
if (this._kuFlowAuthorizationTokenProvider != null) {
await this._kuFlowAuthorizationTokenProvider.close();
this._kuFlowAuthorizationTokenProvider = undefined;
}
}
}
exports.KuFlowTemporalConnection = KuFlowTemporalConnection;
//# sourceMappingURL=kuflow-temporal-connection.js.map