Skip to content

Commit df1693c

Browse files
authored
Merge pull request #2595 from kuzzleio/2-dev
release: 2-dev to master
2 parents c33f0dc + 9478dc2 commit df1693c

File tree

11 files changed

+237
-6
lines changed

11 files changed

+237
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
code: true
3+
type: page
4+
title: getSettings | API | Core
5+
---
6+
7+
# getSettings
8+
9+
Retrieves the Elasticsearch index settings for the specified Kuzzle collection.
10+
11+
---
12+
13+
## Query Syntax
14+
15+
### HTTP
16+
17+
```http
18+
URL: http://kuzzle:7512/<index>/<collection>/_settings
19+
Method: GET
20+
```
21+
22+
### Other protocols
23+
24+
```js
25+
{
26+
"index": "<index>",
27+
"collection": "<collection>",
28+
"controller": "collection",
29+
"action": "getSettings",
30+
}
31+
```
32+
33+
---
34+
35+
## Arguments
36+
37+
- `collection`: collection name
38+
- `index`: index name
39+
40+
---
41+
42+
## Response
43+
44+
Returns a setting object with the following structure:
45+
46+
```js
47+
{
48+
"status": 200,
49+
"error": null,
50+
"action": "getSettings",
51+
"controller": "collection",
52+
"collection": "<collection>",
53+
"index": "<index>",
54+
"headers": {},
55+
"result": {
56+
"routing": {
57+
"allocation": {
58+
"include": {
59+
"_tier_preference": "data_content"
60+
}
61+
}
62+
},
63+
"number_of_shards": "1",
64+
"provided_name": "&platform.config",
65+
"creation_date": "1738682329397",
66+
"number_of_replicas": "1",
67+
"uuid": "aY0IBbKJSvuIrwqqYyKkUw",
68+
"version": {
69+
"created": "7160299"
70+
}
71+
},
72+
}
73+
```
74+
75+
---
76+
77+
## Possible errors
78+
79+
- [Common errors](/core/2/api/errors/types#common-errors)
80+
- [NotFoundError](/core/2/api/errors/types#notfounderror)

doc/2/guides/main-concepts/api/index.md

+22-2
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,29 @@ This endpoint is accessible with the route `GET /_healthcheck`.
9898
curl "http://localhost:7512/_healthcheck"
9999
```
100100

101-
This route does not require any authentication. It returns a `200` status code if the server is up and running.
101+
This route does not require any authentication. It returns a `200` status code if the Kuzzle server is started.
102102

103-
This is useful when kuzzle is deployed inside a Kubernetes cluster and you want to configure probes to check the server.
103+
This is useful when Kuzzle is deployed inside a Kubernetes cluster and you want to configure a [`livenessProbe`](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request) to check the Kuzzle server is started.
104+
105+
#### Ready endpoint
106+
107+
Kuzzle exposes a readiness endpoint.
108+
109+
This endpoint is accessible with the route `GET /_ready`.
110+
111+
```bash
112+
curl "http://localhost:7512/_ready"
113+
```
114+
115+
This route does not require any authentication. It returns a `200` status code if the server is running and ready to accept new incoming requests.
116+
It returns a `503` status code if:
117+
- The Kuzzle server state is one of the following:
118+
- Node starting procedure has not finished yet.
119+
- Node is shutting down.
120+
- The cluster does not have enough nodes to be considered as healthy.
121+
- The Kuzzle server is overloaded (meaning the number of requests in the queue is above the [configured threshold](https://github.com/kuzzleio/kuzzle/blob/c33f0dcb904b01941c0967450dc52848ba3456d7/.kuzzlerc.sample.jsonc#L92)).
122+
123+
This is useful when Kuzzle is deployed inside a Kubernetes cluster and you want to configure a [`readinessProbe`](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes) to check the Kuzzle server is ready to accept new incoming requests.
104124

105125
---
106126

docker/images/elasticsearch/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ARG ELASTICSEARCH_VERSION="7.17.25"
1+
ARG ELASTICSEARCH_VERSION="7.17.26"
22
FROM docker.elastic.co/elasticsearch/elasticsearch:${ELASTICSEARCH_VERSION}
33

44
LABEL maintainer="kuzzle" contact="<[email protected]>"

docker/scripts/start-kuzzle-test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,30 @@ app.controller.register("tests", {
490490
});
491491
},
492492
},
493+
simulateOutage: {
494+
http: [{ verb: "get", path: "/tests/simulate-outage" }],
495+
handler: async (request: KuzzleRequest) => {
496+
const outageType = request.getString("type");
497+
498+
switch (outageType) {
499+
case "overload":
500+
global.kuzzle.funnel.overloaded = true;
501+
break;
502+
case "nodeNotStarted":
503+
global.kuzzle.state = 1;
504+
break;
505+
default:
506+
break;
507+
}
508+
},
509+
},
510+
clearOutage: {
511+
http: [{ verb: "get", path: "/tests/clear-outage" }],
512+
handler: async () => {
513+
global.kuzzle.funnel.overloaded = false;
514+
global.kuzzle.state = 2;
515+
},
516+
},
493517
},
494518
});
495519

features/CollectionController.feature

+13
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@ Feature: Collection Controller
6969
| createdAt | { "type": "date" } |
7070
| updatedAt | { "type": "date" } |
7171

72+
73+
# collection:getSettings =====================================================
74+
75+
Scenario: Get collection settings
76+
Given an index "nyc-open-data"
77+
And I "create" the collection "nyc-open-data":"green-taxi" with:
78+
| mappings | { "dynamic": "strict", "properties": { "name": { "type": "keyword" } } } |
79+
When I successfully execute the action "collection":"getSettings" with args:
80+
| index | "nyc-open-data" |
81+
| collection | "green-taxi" |
82+
Then I should receive a result matching:
83+
| number_of_shards | "1" |
84+
7285
# collection:delete ==========================================================
7386

7487
Scenario: Delete a collection

jest/network/network/ready.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import rp from "request-promise";
2+
3+
test("Check _ready result", async () => {
4+
const response = rp.get({
5+
uri: "http://localhost:17510/_ready",
6+
});
7+
8+
await expect(response).resolves.not.toThrow(); // Should return 200
9+
});
10+
11+
test("Check _ready during node startup", async () => {
12+
await rp.get({
13+
uri: "http://localhost:17510/tests/simulate-outage?type=nodeNotStarted",
14+
});
15+
16+
const response = rp.get({
17+
uri: "http://localhost:17510/_ready",
18+
});
19+
20+
await expect(response).rejects; // Should return 503
21+
22+
await rp.get({
23+
uri: "http://localhost:17510/tests/clear-outage",
24+
});
25+
});
26+
27+
test("Check _ready during node overload", async () => {
28+
await rp.get({
29+
uri: "http://localhost:17510/tests/simulate-outage?type=overload",
30+
});
31+
32+
const response = rp.get({
33+
uri: "http://localhost:17510/_ready",
34+
});
35+
36+
await expect(response).rejects; // Should return 503
37+
38+
await rp.get({
39+
uri: "http://localhost:17510/tests/clear-outage",
40+
});
41+
});
42+

lib/api/controllers/collectionController.js

+18
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class CollectionController extends NativeController {
3636
"deleteSpecifications",
3737
"exists",
3838
"getMapping",
39+
"getSettings",
3940
"getSpecifications",
4041
"list",
4142
"refresh",
@@ -97,6 +98,23 @@ class CollectionController extends NativeController {
9798
return this._filterMappingResponse(mapping);
9899
}
99100

101+
/**
102+
* Get the collection settings
103+
*
104+
* @param {Request} request
105+
* @returns {Promise.<Object>}
106+
*/
107+
async getSettings(request) {
108+
const { index, collection } = request.getIndexAndCollection();
109+
110+
return this.ask(
111+
"core:storage:public:collection:settings:get",
112+
index,
113+
collection,
114+
{},
115+
);
116+
}
117+
100118
/**
101119
* Get the collection validation specifications
102120
*

lib/api/httpRoutes.js

+6
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ const routes = [
140140
controller: "collection",
141141
action: "getMapping",
142142
},
143+
{
144+
verb: "get",
145+
path: "/:index/:collection/_settings",
146+
controller: "collection",
147+
action: "getSettings",
148+
},
143149
{
144150
verb: "get",
145151
path: "/:index/:collection/_search",

lib/core/backend/backend.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ export class Backend {
7676
private _kuzzle: any;
7777
private _name: string;
7878
private _sdk: EmbeddedSDK;
79-
80-
protected started = false;
79+
private _started: boolean;
8180

8281
protected _pipes = {};
8382
protected _hooks = {};
@@ -431,6 +430,14 @@ export class Backend {
431430
};
432431
}
433432

433+
get started() {
434+
return this._started;
435+
}
436+
437+
protected set started(started: boolean) {
438+
this._started = started;
439+
}
440+
434441
/**
435442
* Try to read the current commit hash.
436443
*/

lib/core/network/router.js

+22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const { Request } = require("../../api/request");
2525
const kerror = require("../../kerror");
2626
const HttpRouter = require("./httpRouter");
2727
const { removeStacktrace } = require("../../util/stackTrace");
28+
const kuzzleStateEnum = require("../../kuzzle/kuzzleStateEnum");
2829

2930
/**
3031
* @class Router
@@ -148,6 +149,27 @@ class Router {
148149
cb(request);
149150
});
150151

152+
this.http.get("_ready", (request, cb) => {
153+
let status = 200;
154+
155+
if (
156+
global.kuzzle.state !== kuzzleStateEnum.RUNNING ||
157+
global.kuzzle.funnel.overloaded
158+
) {
159+
status = 503;
160+
}
161+
162+
request.response.configure({
163+
status: status,
164+
});
165+
166+
/**
167+
* By avoiding using the funnel, we avoid the request to be logged
168+
* This is useful for ochestrators healthchecks
169+
*/
170+
cb(request);
171+
});
172+
151173
for (const route of routes) {
152174
const verb = route.verb.toLowerCase();
153175

test/api/controllers/collectionController.test.js

-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,6 @@ describe("Test: collection controller", () => {
651651
index,
652652
collection,
653653
);
654-
655654
should(response).be.instanceof(Object);
656655
should(response).match({
657656
acknowledged: true,

0 commit comments

Comments
 (0)