Skip to content

Commit

Permalink
added checks for server versions to fail kv or objectstore if not in …
Browse files Browse the repository at this point in the history
…the required versions as per ADR issue (#371)
  • Loading branch information
aricart committed Sep 22, 2022
1 parent eb1f69e commit adf39af
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
8 changes: 7 additions & 1 deletion nats-base-client/kv.ts
Expand Up @@ -186,9 +186,15 @@ export class Bucket implements KV, KvRemove {
name: string,
opts: Partial<KvOptions> = {},
): Promise<KV> {
const jsi = js as JetStreamClientImpl;
const { ok, min } = jsi.nc.features.get(Feature.JS_KV);
if (!ok) {
return Promise.reject(
new Error(`kv is only supported on servers ${min} or better`),
);
}
validateBucket(name);
const to = opts.timeout || 2000;
const jsi = js as JetStreamClientImpl;
let jsopts = jsi.opts || {} as JetStreamOptions;
jsopts = Object.assign(jsopts, { timeout: to });
const jsm = await jsi.nc.jetstreamManager(jsopts);
Expand Down
8 changes: 7 additions & 1 deletion nats-base-client/objectstore.ts
Expand Up @@ -45,6 +45,7 @@ import { consumerOpts } from "./jsconsumeropts.ts";
import { NatsError } from "./mod.ts";
import { QueuedIterator, QueuedIteratorImpl } from "./queued_iterator.ts";
import { SHA256 } from "./sha256.js";
import { Feature } from "./semver.ts";

export const osPrefix = "OBJ_";

Expand Down Expand Up @@ -717,8 +718,13 @@ export class ObjectStoreImpl implements ObjectStore {
),
);
}

const jsi = js as JetStreamClientImpl;
const { ok, min } = jsi.nc.features.get(Feature.JS_OBJECTSTORE);
if (!ok) {
return Promise.reject(
new Error(`objectstore is only supported on servers ${min} or better`),
);
}
let jsopts = jsi.opts || {} as JetStreamOptions;
const to = jsopts.timeout || 2000;
jsopts = Object.assign(jsopts, { timeout: to });
Expand Down
4 changes: 4 additions & 0 deletions nats-base-client/semver.ts
Expand Up @@ -23,6 +23,8 @@ export function compare(a: SemVer, b: SemVer): number {
}

export enum Feature {
JS_KV = "js_kv",
JS_OBJECTSTORE = "js_objectstore",
JS_PULL_MAX_BYTES = "js_pull_max_bytes",
JS_NEW_CONSUMER_CREATE_API = "js_new_consumer_create",
JS_ALLOW_DIRECT = "js_allow_direct",
Expand Down Expand Up @@ -69,6 +71,8 @@ export class Features {
v = parseSemVer(v);
}
this.server = v;
this.set(Feature.JS_KV, "2.6.2");
this.set(Feature.JS_OBJECTSTORE, "2.6.3");
this.set(Feature.JS_PULL_MAX_BYTES, "2.8.3");
this.set(Feature.JS_NEW_CONSUMER_CREATE_API, "2.9.0");
this.set(Feature.JS_ALLOW_DIRECT, "2.9.0");
Expand Down
43 changes: 43 additions & 0 deletions tests/jetstream_test.ts
Expand Up @@ -3733,3 +3733,46 @@ Deno.test("jetstream - filter_subject consumer update", async () => {
assertEquals(ci.config.filter_subject, "foo.baz");
await cleanup(ns, nc);
});

Deno.test("jetstream - kv and object store views reject in older servers", async () => {
const { ns, nc } = await setup(jetstreamServerConf({
max_payload: 1024 * 1024,
}, true));

const nci = nc as NatsConnectionImpl;
const js = nc.jetstream();
async function t(version: string, kv: boolean, os: boolean): Promise<void> {
nci.features.update(version);

if (!kv) {
await assertRejects(
async () => {
await js.views.kv(nuid.next());
},
Error,
`kv is only supported on servers 2.6.2 or better`,
);
} else {
await js.views.kv(nuid.next());
}

if (!os) {
await assertRejects(
async () => {
await js.views.os(nuid.next());
},
Error,
`objectstore is only supported on servers 2.6.3 or better`,
);
} else {
await js.views.os(nuid.next());
}
}

await t("2.6.1", false, false);
await t("2.6.2", true, false);
await t("2.6.3", true, true);
await t("2.6.4", true, true);

await cleanup(ns, nc);
});

0 comments on commit adf39af

Please sign in to comment.