UNPKG

9.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const cluster = require("cluster");
4const stringify = require("json-stringify-safe");
5const applicationEvent_1 = require("./internal/env/applicationEvent");
6const ClusterMasterRequestProcessor_1 = require("./internal/transport/cluster/ClusterMasterRequestProcessor");
7const ClusterWorkerRequestProcessor_1 = require("./internal/transport/cluster/ClusterWorkerRequestProcessor");
8const EventStoringAutomationEventListener_1 = require("./internal/transport/EventStoringAutomationEventListener");
9const ExpressRequestProcessor_1 = require("./internal/transport/express/ExpressRequestProcessor");
10const ExpressServer_1 = require("./internal/transport/express/ExpressServer");
11const MetricEnabledAutomationEventListener_1 = require("./internal/transport/MetricEnabledAutomationEventListener");
12const showStartupMessages_1 = require("./internal/transport/showStartupMessages");
13const DefaultWebSocketRequestProcessor_1 = require("./internal/transport/websocket/DefaultWebSocketRequestProcessor");
14const payloads_1 = require("./internal/transport/websocket/payloads");
15const WebSocketClient_1 = require("./internal/transport/websocket/WebSocketClient");
16const shutdown_1 = require("./internal/util/shutdown");
17const string_1 = require("./internal/util/string");
18const BuildableAutomationServer_1 = require("./server/BuildableAutomationServer");
19const statsd_1 = require("./spi/statsd/statsd");
20const logger_1 = require("./util/logger");
21const redact_1 = require("./util/redact");
22class AutomationClient {
23 constructor(configuration) {
24 this.configuration = configuration;
25 this.defaultListeners = [
26 new MetricEnabledAutomationEventListener_1.MetricEnabledAutomationEventListener(),
27 new EventStoringAutomationEventListener_1.EventStoringAutomationEventListener(),
28 new showStartupMessages_1.StartupMessageAutomationEventListener(),
29 new showStartupMessages_1.StartupTimeMessageUatomationEventListener(),
30 ];
31 this.automations = new BuildableAutomationServer_1.BuildableAutomationServer(configuration);
32 global.__runningAutomationClient = this;
33 }
34 get automationServer() {
35 return this.automations;
36 }
37 withCommandHandler(chm) {
38 this.automations.registerCommandHandler(chm);
39 return this;
40 }
41 withEventHandler(event) {
42 this.automations.registerEventHandler(event);
43 return this;
44 }
45 withIngester(ingester) {
46 this.automations.registerIngester(ingester);
47 return this;
48 }
49 processCommand(command, callback) {
50 if (this.webSocketHandler) {
51 return this.webSocketHandler.processCommand(command, callback);
52 }
53 else if (this.httpHandler) {
54 return this.httpHandler.processCommand(command, callback);
55 }
56 else {
57 throw new Error("No request processor available");
58 }
59 }
60 processEvent(event, callback) {
61 if (this.webSocketHandler) {
62 return this.webSocketHandler.processEvent(event, callback);
63 }
64 else if (this.httpHandler) {
65 return this.httpHandler.processEvent(event, callback);
66 }
67 else {
68 throw new Error("No request processor available");
69 }
70 }
71 run() {
72 this.configureRedactions();
73 logger_1.configureLogging(logger_1.clientLoggingConfiguration(this.configuration));
74 this.configureShutdown();
75 this.configureStatsd();
76 const clientSig = `${this.configuration.name}:${this.configuration.version}`;
77 const clientConf = stringify(this.configuration, string_1.obfuscateJson);
78 if (!this.configuration.cluster.enabled) {
79 logger_1.logger.info(`Starting Atomist automation client ${clientSig}`);
80 logger_1.logger.debug(`Using automation client configuration: ${clientConf}`);
81 if (this.configuration.ws.enabled) {
82 return Promise.all([
83 this.runWs(() => this.setupWebSocketRequestHandler()),
84 this.runHttp(() => this.setupExpressRequestHandler()),
85 ])
86 .then(() => this.setupApplicationEvents())
87 .then(() => this.raiseStartupEvent());
88 }
89 else {
90 return this.runHttp(() => this.setupExpressRequestHandler())
91 .then(() => this.setupApplicationEvents())
92 .then(() => this.raiseStartupEvent());
93 }
94 }
95 else if (cluster.isMaster) {
96 logger_1.logger.info(`Starting Atomist automation client master ${clientSig}`);
97 logger_1.logger.debug(`Using automation client configuration: ${clientConf}`);
98 this.webSocketHandler = this.setupWebSocketClusterRequestHandler();
99 return this.webSocketHandler.run()
100 .then(() => {
101 return Promise.all([
102 this.runWs(() => this.webSocketHandler),
103 this.runHttp(() => this.setupExpressRequestHandler()),
104 ])
105 .then(() => this.setupApplicationEvents())
106 .then(() => this.raiseStartupEvent());
107 });
108 }
109 else if (cluster.isWorker) {
110 logger_1.logger.info(`Starting Atomist automation client worker ${clientSig}`);
111 return Promise.resolve(this.setupWebSocketClusterWorkerRequestHandler())
112 .then(workerProcessor => {
113 this.webSocketHandler = workerProcessor;
114 return this.raiseStartupEvent();
115 });
116 }
117 }
118 configureRedactions() {
119 if (!!this.configuration.redact && !!this.configuration.redact.patterns) {
120 this.configuration.redact.patterns.forEach(p => {
121 let regexp;
122 if (typeof p.regexp === "string") {
123 regexp = new RegExp(p.regexp, "g");
124 }
125 else {
126 regexp = p.regexp;
127 }
128 redact_1.addRedaction(regexp, p.replacement);
129 });
130 }
131 }
132 raiseStartupEvent() {
133 return [...this.defaultListeners, ...this.configuration.listeners].filter(l => l.startupSuccessful)
134 .map(l => () => l.startupSuccessful(this))
135 .reduce((p, f) => p.then(f), Promise.resolve());
136 }
137 configureShutdown() {
138 const gracePeriod = shutdown_1.terminationGracePeriod(this.configuration);
139 shutdown_1.setForceExitTimeout(gracePeriod * 10);
140 }
141 configureStatsd() {
142 if (this.configuration.statsd.enabled === true) {
143 this.defaultListeners.push(new statsd_1.StatsdAutomationEventListener(this.configuration));
144 }
145 }
146 setupWebSocketClusterRequestHandler() {
147 return new ClusterMasterRequestProcessor_1.ClusterMasterRequestProcessor(this.automations, this.configuration, [...this.defaultListeners, ...this.configuration.listeners], this.configuration.cluster.workers, this.configuration.cluster.maxConcurrentPerWorker);
148 }
149 setupWebSocketClusterWorkerRequestHandler() {
150 return ClusterWorkerRequestProcessor_1.startWorker(this.automations, this.configuration, [...this.defaultListeners, ...this.configuration.listeners]);
151 }
152 setupWebSocketRequestHandler() {
153 return new DefaultWebSocketRequestProcessor_1.DefaultWebSocketRequestProcessor(this.automations, this.configuration, [...this.defaultListeners, ...this.configuration.listeners]);
154 }
155 setupApplicationEvents() {
156 if (this.configuration.applicationEvents.enabled) {
157 if (this.configuration.applicationEvents.workspaceId) {
158 return applicationEvent_1.registerApplicationEvents(this.configuration.applicationEvents.workspaceId, this.configuration);
159 }
160 else if (this.configuration.workspaceIds.length > 0) {
161 return applicationEvent_1.registerApplicationEvents(this.configuration.workspaceIds[0], this.configuration);
162 }
163 }
164 return Promise.resolve();
165 }
166 setupExpressRequestHandler() {
167 return new ExpressRequestProcessor_1.ExpressRequestProcessor(this.automations, this.configuration, [...this.defaultListeners, ...this.configuration.listeners]);
168 }
169 runWs(handlerMaker) {
170 const payloadOptions = {};
171 if (this.configuration.ws && this.configuration.ws.compress) {
172 payloadOptions.accept_encoding = "gzip";
173 }
174 this.webSocketHandler = handlerMaker();
175 this.webSocketClient = new WebSocketClient_1.WebSocketClient(() => payloads_1.prepareRegistration(this.automations.automations, payloadOptions, this.configuration.metadata), this.configuration, this.webSocketHandler);
176 return this.webSocketClient.start();
177 }
178 runHttp(handlerMaker) {
179 if (!this.configuration.http.enabled) {
180 return;
181 }
182 this.httpHandler = handlerMaker();
183 this.httpServer = new ExpressServer_1.ExpressServer(this.automations, this.configuration, this.httpHandler);
184 return this.httpServer.run();
185 }
186}
187exports.AutomationClient = AutomationClient;
188function automationClient(configuration) {
189 const client = new AutomationClient(configuration);
190 configuration.commands.forEach(c => {
191 client.withCommandHandler(c);
192 });
193 configuration.events.forEach(e => {
194 client.withEventHandler(e);
195 });
196 configuration.ingesters.forEach(e => {
197 client.withIngester(e);
198 });
199 return client;
200}
201exports.automationClient = automationClient;
202//# sourceMappingURL=automationClient.js.map
\No newline at end of file