Skip to content

Commit 63582c7

Browse files
committed
Add support for the health check
1 parent b0201f9 commit 63582c7

8 files changed

Lines changed: 1141 additions & 11 deletions

File tree

knip.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"**/fixtures/**",
88
"**/fixtures-*/**",
99
"packages/bridge/src/worker.ts",
10+
"packages/grpc/src/proto/*.d.ts",
1011
"its/**",
1112
"tools/header.ts",
1213
"tools/new-plugin.ts"

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"bridge:build:cov": "npm run bridge:build:fast && npm run bridge:test:cov",
2626
"bridge:build:fast": "npm run _:bridge:clear && npm run generate-meta && npm run bridge:compile",
2727
"bbf": "npm run bridge:build:fast",
28-
"grpc:generate-proto": "pbjs -t static-module -w packages/grpc/src/proto/es6-wrapper.js --es6 -o packages/grpc/src/proto/language_analyzer.js packages/grpc/src/proto/language_analyzer.proto && pbts -o packages/grpc/src/proto/language_analyzer.d.ts packages/grpc/src/proto/language_analyzer.js",
28+
"grpc:generate-proto": "pbjs -t static-module -w packages/grpc/src/proto/es6-wrapper.js --es6 -o packages/grpc/src/proto/language_analyzer.js packages/grpc/src/proto/language_analyzer.proto && pbts -o packages/grpc/src/proto/language_analyzer.d.ts packages/grpc/src/proto/language_analyzer.js && pbjs -t static-module -w packages/grpc/src/proto/es6-wrapper.js --es6 -o packages/grpc/src/proto/health.js packages/grpc/src/proto/health.proto && pbts -o packages/grpc/src/proto/health.d.ts packages/grpc/src/proto/health.js",
2929
"grpc:bundle": "node esbuild-grpc.mjs",
3030
"grpc:build": "npm run bridge:build:fast && npm run grpc:bundle",
3131
"plugin:build": "mvn install",
@@ -35,7 +35,7 @@
3535
"precommit": "pretty-quick --staged",
3636
"postinstall": "patch-package",
3737
"count-rules": "tsx tools/count-rules.ts",
38-
"_:bridge:copy-protofiles": "cpy --flat packages/jsts/src/parsers/estree.proto lib/jsts/src/parsers && cpy --flat packages/grpc/src/proto/language_analyzer.js packages/grpc/src/proto/language_analyzer.d.ts lib/grpc/src/proto",
38+
"_:bridge:copy-protofiles": "cpy --flat packages/jsts/src/parsers/estree.proto lib/jsts/src/parsers && cpy --flat packages/grpc/src/proto/language_analyzer.js packages/grpc/src/proto/language_analyzer.d.ts packages/grpc/src/proto/health.js packages/grpc/src/proto/health.d.ts lib/grpc/src/proto",
3939
"_:bridge:clear": "rimraf --glob lib/*",
4040
"_:plugin:prepare-bridge": "npm run bridge:bundle && npm pack --ignore-scripts && npm run _:plugin:copy-bridge",
4141
"_:plugin:copy-bridge": "cpy sonarjs-1.0.0.tgz sonar-plugin/sonar-javascript-plugin/target/classes && cpy sonarjs-1.0.0.tgz sonar-plugin/standalone/target/classes",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SonarQube JavaScript Plugin
3+
* Copyright (C) 2011-2025 SonarSource Sàrl
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
import * as grpc from '@grpc/grpc-js';
18+
import { grpc as healthProto } from './proto/health.js';
19+
import { info } from '../../shared/src/helpers/logging.js';
20+
21+
/**
22+
* gRPC handler for the Health Check RPC
23+
* Implements the standard grpc.health.v1.Health service
24+
*/
25+
export async function healthCheckHandler(
26+
call: grpc.ServerUnaryCall<
27+
healthProto.health.v1.IHealthCheckRequest,
28+
healthProto.health.v1.IHealthCheckResponse
29+
>,
30+
callback: grpc.sendUnaryData<healthProto.health.v1.IHealthCheckResponse>,
31+
): Promise<void> {
32+
const request = call.request;
33+
const serviceName = request.service || '';
34+
35+
info(`Health check request for service: "${serviceName}"`);
36+
37+
const isKnownService = serviceName === '' || serviceName === 'analyzer.LanguageAnalyzerService';
38+
39+
if (!isKnownService) {
40+
info(`Unknown service requested: "${serviceName}"`);
41+
callback({
42+
code: grpc.status.NOT_FOUND,
43+
message: `Service "${serviceName}" not found`,
44+
});
45+
return;
46+
}
47+
48+
const response: healthProto.health.v1.IHealthCheckResponse = {
49+
status: healthProto.health.v1.HealthCheckResponse.ServingStatus.SERVING,
50+
};
51+
52+
callback(null, response);
53+
}
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
import * as $protobuf from 'protobufjs';
2+
import Long = require('long');
3+
/** Namespace grpc. */
4+
export namespace grpc {
5+
/** Namespace health. */
6+
namespace health {
7+
/** Namespace v1. */
8+
namespace v1 {
9+
/** Properties of a HealthCheckRequest. */
10+
interface IHealthCheckRequest {
11+
/** HealthCheckRequest service */
12+
service?: string | null;
13+
}
14+
15+
/** Represents a HealthCheckRequest. */
16+
class HealthCheckRequest implements IHealthCheckRequest {
17+
/**
18+
* Constructs a new HealthCheckRequest.
19+
* @param [properties] Properties to set
20+
*/
21+
constructor(properties?: grpc.health.v1.IHealthCheckRequest);
22+
23+
/** HealthCheckRequest service. */
24+
public service: string;
25+
26+
/**
27+
* Creates a new HealthCheckRequest instance using the specified properties.
28+
* @param [properties] Properties to set
29+
* @returns HealthCheckRequest instance
30+
*/
31+
public static create(
32+
properties?: grpc.health.v1.IHealthCheckRequest,
33+
): grpc.health.v1.HealthCheckRequest;
34+
35+
/**
36+
* Encodes the specified HealthCheckRequest message. Does not implicitly {@link grpc.health.v1.HealthCheckRequest.verify|verify} messages.
37+
* @param message HealthCheckRequest message or plain object to encode
38+
* @param [writer] Writer to encode to
39+
* @returns Writer
40+
*/
41+
public static encode(
42+
message: grpc.health.v1.IHealthCheckRequest,
43+
writer?: $protobuf.Writer,
44+
): $protobuf.Writer;
45+
46+
/**
47+
* Encodes the specified HealthCheckRequest message, length delimited. Does not implicitly {@link grpc.health.v1.HealthCheckRequest.verify|verify} messages.
48+
* @param message HealthCheckRequest message or plain object to encode
49+
* @param [writer] Writer to encode to
50+
* @returns Writer
51+
*/
52+
public static encodeDelimited(
53+
message: grpc.health.v1.IHealthCheckRequest,
54+
writer?: $protobuf.Writer,
55+
): $protobuf.Writer;
56+
57+
/**
58+
* Decodes a HealthCheckRequest message from the specified reader or buffer.
59+
* @param reader Reader or buffer to decode from
60+
* @param [length] Message length if known beforehand
61+
* @returns HealthCheckRequest
62+
* @throws {Error} If the payload is not a reader or valid buffer
63+
* @throws {$protobuf.util.ProtocolError} If required fields are missing
64+
*/
65+
public static decode(
66+
reader: $protobuf.Reader | Uint8Array,
67+
length?: number,
68+
): grpc.health.v1.HealthCheckRequest;
69+
70+
/**
71+
* Decodes a HealthCheckRequest message from the specified reader or buffer, length delimited.
72+
* @param reader Reader or buffer to decode from
73+
* @returns HealthCheckRequest
74+
* @throws {Error} If the payload is not a reader or valid buffer
75+
* @throws {$protobuf.util.ProtocolError} If required fields are missing
76+
*/
77+
public static decodeDelimited(
78+
reader: $protobuf.Reader | Uint8Array,
79+
): grpc.health.v1.HealthCheckRequest;
80+
81+
/**
82+
* Verifies a HealthCheckRequest message.
83+
* @param message Plain object to verify
84+
* @returns `null` if valid, otherwise the reason why it is not
85+
*/
86+
public static verify(message: { [k: string]: any }): string | null;
87+
88+
/**
89+
* Creates a HealthCheckRequest message from a plain object. Also converts values to their respective internal types.
90+
* @param object Plain object
91+
* @returns HealthCheckRequest
92+
*/
93+
public static fromObject(object: { [k: string]: any }): grpc.health.v1.HealthCheckRequest;
94+
95+
/**
96+
* Creates a plain object from a HealthCheckRequest message. Also converts values to other types if specified.
97+
* @param message HealthCheckRequest
98+
* @param [options] Conversion options
99+
* @returns Plain object
100+
*/
101+
public static toObject(
102+
message: grpc.health.v1.HealthCheckRequest,
103+
options?: $protobuf.IConversionOptions,
104+
): { [k: string]: any };
105+
106+
/**
107+
* Converts this HealthCheckRequest to JSON.
108+
* @returns JSON object
109+
*/
110+
public toJSON(): { [k: string]: any };
111+
112+
/**
113+
* Gets the default type url for HealthCheckRequest
114+
* @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
115+
* @returns The default type url
116+
*/
117+
public static getTypeUrl(typeUrlPrefix?: string): string;
118+
}
119+
120+
/** Properties of a HealthCheckResponse. */
121+
interface IHealthCheckResponse {
122+
/** HealthCheckResponse status */
123+
status?: grpc.health.v1.HealthCheckResponse.ServingStatus | null;
124+
}
125+
126+
/** Represents a HealthCheckResponse. */
127+
class HealthCheckResponse implements IHealthCheckResponse {
128+
/**
129+
* Constructs a new HealthCheckResponse.
130+
* @param [properties] Properties to set
131+
*/
132+
constructor(properties?: grpc.health.v1.IHealthCheckResponse);
133+
134+
/** HealthCheckResponse status. */
135+
public status: grpc.health.v1.HealthCheckResponse.ServingStatus;
136+
137+
/**
138+
* Creates a new HealthCheckResponse instance using the specified properties.
139+
* @param [properties] Properties to set
140+
* @returns HealthCheckResponse instance
141+
*/
142+
public static create(
143+
properties?: grpc.health.v1.IHealthCheckResponse,
144+
): grpc.health.v1.HealthCheckResponse;
145+
146+
/**
147+
* Encodes the specified HealthCheckResponse message. Does not implicitly {@link grpc.health.v1.HealthCheckResponse.verify|verify} messages.
148+
* @param message HealthCheckResponse message or plain object to encode
149+
* @param [writer] Writer to encode to
150+
* @returns Writer
151+
*/
152+
public static encode(
153+
message: grpc.health.v1.IHealthCheckResponse,
154+
writer?: $protobuf.Writer,
155+
): $protobuf.Writer;
156+
157+
/**
158+
* Encodes the specified HealthCheckResponse message, length delimited. Does not implicitly {@link grpc.health.v1.HealthCheckResponse.verify|verify} messages.
159+
* @param message HealthCheckResponse message or plain object to encode
160+
* @param [writer] Writer to encode to
161+
* @returns Writer
162+
*/
163+
public static encodeDelimited(
164+
message: grpc.health.v1.IHealthCheckResponse,
165+
writer?: $protobuf.Writer,
166+
): $protobuf.Writer;
167+
168+
/**
169+
* Decodes a HealthCheckResponse message from the specified reader or buffer.
170+
* @param reader Reader or buffer to decode from
171+
* @param [length] Message length if known beforehand
172+
* @returns HealthCheckResponse
173+
* @throws {Error} If the payload is not a reader or valid buffer
174+
* @throws {$protobuf.util.ProtocolError} If required fields are missing
175+
*/
176+
public static decode(
177+
reader: $protobuf.Reader | Uint8Array,
178+
length?: number,
179+
): grpc.health.v1.HealthCheckResponse;
180+
181+
/**
182+
* Decodes a HealthCheckResponse message from the specified reader or buffer, length delimited.
183+
* @param reader Reader or buffer to decode from
184+
* @returns HealthCheckResponse
185+
* @throws {Error} If the payload is not a reader or valid buffer
186+
* @throws {$protobuf.util.ProtocolError} If required fields are missing
187+
*/
188+
public static decodeDelimited(
189+
reader: $protobuf.Reader | Uint8Array,
190+
): grpc.health.v1.HealthCheckResponse;
191+
192+
/**
193+
* Verifies a HealthCheckResponse message.
194+
* @param message Plain object to verify
195+
* @returns `null` if valid, otherwise the reason why it is not
196+
*/
197+
public static verify(message: { [k: string]: any }): string | null;
198+
199+
/**
200+
* Creates a HealthCheckResponse message from a plain object. Also converts values to their respective internal types.
201+
* @param object Plain object
202+
* @returns HealthCheckResponse
203+
*/
204+
public static fromObject(object: { [k: string]: any }): grpc.health.v1.HealthCheckResponse;
205+
206+
/**
207+
* Creates a plain object from a HealthCheckResponse message. Also converts values to other types if specified.
208+
* @param message HealthCheckResponse
209+
* @param [options] Conversion options
210+
* @returns Plain object
211+
*/
212+
public static toObject(
213+
message: grpc.health.v1.HealthCheckResponse,
214+
options?: $protobuf.IConversionOptions,
215+
): { [k: string]: any };
216+
217+
/**
218+
* Converts this HealthCheckResponse to JSON.
219+
* @returns JSON object
220+
*/
221+
public toJSON(): { [k: string]: any };
222+
223+
/**
224+
* Gets the default type url for HealthCheckResponse
225+
* @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
226+
* @returns The default type url
227+
*/
228+
public static getTypeUrl(typeUrlPrefix?: string): string;
229+
}
230+
231+
namespace HealthCheckResponse {
232+
/** ServingStatus enum. */
233+
enum ServingStatus {
234+
UNKNOWN = 0,
235+
SERVING = 1,
236+
NOT_SERVING = 2,
237+
SERVICE_UNKNOWN = 3,
238+
}
239+
}
240+
241+
/** Represents a Health */
242+
class Health extends $protobuf.rpc.Service {
243+
/**
244+
* Constructs a new Health service.
245+
* @param rpcImpl RPC implementation
246+
* @param [requestDelimited=false] Whether requests are length-delimited
247+
* @param [responseDelimited=false] Whether responses are length-delimited
248+
*/
249+
constructor(
250+
rpcImpl: $protobuf.RPCImpl,
251+
requestDelimited?: boolean,
252+
responseDelimited?: boolean,
253+
);
254+
255+
/**
256+
* Creates new Health service using the specified rpc implementation.
257+
* @param rpcImpl RPC implementation
258+
* @param [requestDelimited=false] Whether requests are length-delimited
259+
* @param [responseDelimited=false] Whether responses are length-delimited
260+
* @returns RPC service. Useful where requests and/or responses are streamed.
261+
*/
262+
public static create(
263+
rpcImpl: $protobuf.RPCImpl,
264+
requestDelimited?: boolean,
265+
responseDelimited?: boolean,
266+
): Health;
267+
268+
/**
269+
* Calls Check.
270+
* @param request HealthCheckRequest message or plain object
271+
* @param callback Node-style callback called with the error, if any, and HealthCheckResponse
272+
*/
273+
public check(
274+
request: grpc.health.v1.IHealthCheckRequest,
275+
callback: grpc.health.v1.Health.CheckCallback,
276+
): void;
277+
278+
/**
279+
* Calls Check.
280+
* @param request HealthCheckRequest message or plain object
281+
* @returns Promise
282+
*/
283+
public check(
284+
request: grpc.health.v1.IHealthCheckRequest,
285+
): Promise<grpc.health.v1.HealthCheckResponse>;
286+
}
287+
288+
namespace Health {
289+
/**
290+
* Callback as used by {@link grpc.health.v1.Health#check}.
291+
* @param error Error, if any
292+
* @param [response] HealthCheckResponse
293+
*/
294+
type CheckCallback = (
295+
error: Error | null,
296+
response?: grpc.health.v1.HealthCheckResponse,
297+
) => void;
298+
}
299+
}
300+
}
301+
}

0 commit comments

Comments
 (0)