Skip to content

Commit 0541640

Browse files
committed
Make breaking change to introduce ACTIVE/INACTIVE in returns but allow HOT/COLD in create/update
1 parent 79cb5f5 commit 0541640

File tree

7 files changed

+65
-66
lines changed

7 files changed

+65
-66
lines changed

src/collections/deserialize/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,9 @@ export class Deserialize {
305305
private static activityStatusGRPC(status: TenantActivityStatus): Tenant['activityStatus'] {
306306
switch (status) {
307307
case TenantActivityStatus.TENANT_ACTIVITY_STATUS_COLD:
308-
return 'COLD';
308+
return 'INACTIVE';
309309
case TenantActivityStatus.TENANT_ACTIVITY_STATUS_HOT:
310-
return 'HOT';
310+
return 'ACTIVE';
311311
case TenantActivityStatus.TENANT_ACTIVITY_STATUS_FROZEN:
312312
return 'OFFLOADED';
313313
case TenantActivityStatus.TENANT_ACTIVITY_STATUS_FREEZING:
@@ -322,15 +322,17 @@ export class Deserialize {
322322
public static activityStatusREST(status: TenantREST['activityStatus']): Tenant['activityStatus'] {
323323
switch (status) {
324324
case 'COLD':
325-
return 'COLD';
325+
return 'INACTIVE';
326326
case 'HOT':
327-
return 'HOT';
327+
return 'ACTIVE';
328328
case 'FROZEN':
329329
return 'OFFLOADED';
330330
case 'FREEZING':
331331
return 'OFFLOADING';
332332
case 'UNFREEZING':
333333
return 'ONLOADING';
334+
case undefined:
335+
return 'ACTIVE';
334336
default:
335337
throw new Error(`Unsupported tenant activity status: ${status}`);
336338
}

src/collections/query/integration.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ describe('Testing of the collection.query methods with a multi-tenancy collectio
909909
expect(obj2.objects[0].uuid).toEqual(id2);
910910
});
911911

912-
it.skip('should find the objects in their tenants by nearObject', async () => {
912+
it('should find the objects in their tenants by nearObject', async () => {
913913
const obj1 = await collection.withTenant(tenantOne).query.nearObject(id1);
914914
const obj2 = await collection.withTenant(tenantTwo).query.nearObject(id2);
915915
expect(obj1.objects.length).toEqual(1);

src/collections/serialize/index.ts

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { v4 as uuidv4 } from 'uuid';
2-
import { TenantActivityStatus, WhereFilter } from '../../openapi/types.js';
2+
import { WhereFilter } from '../../openapi/types.js';
33
import {
44
BatchObject as BatchObjectGRPC,
55
BatchObject_MultiTargetRefProps,
@@ -82,7 +82,7 @@ import {
8282
import { ReferenceGuards } from '../references/classes.js';
8383
import { Beacon } from '../references/index.js';
8484
import { uuidToBeacon } from '../references/utils.js';
85-
import { Tenant, TenantCreate, TenantUpdate } from '../tenants/types.js';
85+
import { TenantBC, TenantCreate, TenantUpdate } from '../tenants/types.js';
8686
import {
8787
BatchObject,
8888
BatchObjects,
@@ -1137,11 +1137,11 @@ export class Serialize {
11371137
});
11381138
};
11391139

1140-
public static tenantsCreate(tenant: Tenant | TenantCreate): {
1140+
public static tenantsCreate(tenant: TenantBC | TenantCreate): {
11411141
name: string;
11421142
activityStatus?: 'HOT' | 'COLD';
11431143
} {
1144-
let activityStatus: TenantActivityStatus;
1144+
let activityStatus: 'HOT' | 'COLD' | undefined;
11451145
switch (tenant.activityStatus) {
11461146
case 'ACTIVE':
11471147
activityStatus = 'HOT';
@@ -1154,17 +1154,13 @@ export class Serialize {
11541154
case undefined:
11551155
activityStatus = tenant.activityStatus;
11561156
break;
1157-
case 'OFFLOADED':
1158-
throw new WeaviateInvalidInputError(
1159-
'Cannot create a tenant with activity status OFFLOADED. Add objects to the tenant first and then you can update it to OFFLOADED.'
1160-
);
1161-
case 'OFFLOADING':
1157+
case 'FROZEN':
11621158
throw new WeaviateInvalidInputError(
1163-
'Cannot create a tenant with activity status OFFLOADING. This status is a read-only value that the server sets in the processing of making a tenant OFFLOADED.'
1159+
'Invalid activity status. Please provide one of the following: ACTIVE, INACTIVE, HOT, COLD.'
11641160
);
1165-
case 'ONLOADING':
1161+
default:
11661162
throw new WeaviateInvalidInputError(
1167-
'Cannot create a tenant with activity status ONLOADING. This status is a read-only value that the server sets in the processing of making a tenant HOT.'
1163+
'Invalid activity status. Please provide one of the following: ACTIVE, INACTIVE, HOT, COLD.'
11681164
);
11691165
}
11701166
return {
@@ -1174,9 +1170,9 @@ export class Serialize {
11741170
}
11751171

11761172
public static tenantUpdate = (
1177-
tenant: Tenant | TenantUpdate
1173+
tenant: TenantBC | TenantUpdate
11781174
): { name: string; activityStatus: 'HOT' | 'COLD' | 'FROZEN' } => {
1179-
let activityStatus: TenantActivityStatus;
1175+
let activityStatus: 'HOT' | 'COLD' | 'FROZEN';
11801176
switch (tenant.activityStatus) {
11811177
case 'ACTIVE':
11821178
activityStatus = 'HOT';
@@ -1189,15 +1185,12 @@ export class Serialize {
11891185
break;
11901186
case 'HOT':
11911187
case 'COLD':
1188+
case 'FROZEN':
11921189
activityStatus = tenant.activityStatus;
11931190
break;
1194-
case 'OFFLOADING':
1195-
throw new WeaviateInvalidInputError(
1196-
'Cannot create a tenant with activity status OFFLOADING. This status is a read-only value that the server sets in the processing of making a tenant OFFLOADED.'
1197-
);
1198-
case 'ONLOADING':
1191+
default:
11991192
throw new WeaviateInvalidInputError(
1200-
'Cannot create a tenant with activity status ONLOADING. This status is a read-only value that the server sets in the processing of making a tenant HOT.'
1193+
'Invalid activity status. Please provide one of the following: ACTIVE, INACTIVE, HOT, COLD, OFFLOADED.'
12011194
);
12021195
}
12031196
return {

src/collections/tenants/index.ts

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { ConnectionGRPC } from '../../connection/index.js';
22
import { WeaviateUnsupportedFeatureError } from '../../errors.js';
3+
import { Tenant as TenantREST } from '../../openapi/types.js';
34
import { TenantsCreator, TenantsDeleter, TenantsGetter, TenantsUpdater } from '../../schema/index.js';
45
import { DbVersionSupport } from '../../utils/dbVersion.js';
56
import { Deserialize } from '../deserialize/index.js';
67
import { Serialize } from '../serialize/index.js';
7-
import { Tenant, TenantBase, TenantCreate, TenantUpdate } from './types.js';
8+
import { Tenant, TenantBC, TenantBase, TenantCreate, TenantUpdate } from './types.js';
89

910
const checkSupportForGRPCTenantsGetEndpoint = async (dbVersionSupport: DbVersionSupport) => {
1011
const check = await dbVersionSupport.supportsTenantsGetGRPCMethod();
@@ -16,6 +17,13 @@ const parseValueOrValueArray = <V>(value: V | V[]) => (Array.isArray(value) ? va
1617
const parseStringOrTenant = <T extends TenantBase>(tenant: string | T) =>
1718
typeof tenant === 'string' ? tenant : tenant.name;
1819

20+
const parseTenantREST = (tenant: TenantREST): Tenant => {
21+
return {
22+
name: tenant.name!,
23+
activityStatus: Deserialize.activityStatusREST(tenant.activityStatus),
24+
};
25+
};
26+
1927
const tenants = (
2028
connection: ConnectionGRPC,
2129
collection: string,
@@ -31,20 +39,15 @@ const tenants = (
3139
const result: Record<string, Tenant> = {};
3240
tenants.forEach((tenant) => {
3341
if (!tenant.name) return;
34-
result[tenant.name] = {
35-
name: tenant.name!,
36-
activityStatus: Deserialize.activityStatusREST(tenant.activityStatus),
37-
};
42+
result[tenant.name] = parseTenantREST(tenant);
3843
});
3944
return result;
4045
});
4146
return {
42-
create: (tenants: Tenant | TenantCreate | (Tenant | TenantCreate)[]) =>
43-
new TenantsCreator(
44-
connection,
45-
collection,
46-
parseValueOrValueArray(tenants).map(Serialize.tenantsCreate)
47-
).do() as Promise<Tenant[]>,
47+
create: (tenants: TenantBC | TenantCreate | (TenantBC | TenantCreate)[]) =>
48+
new TenantsCreator(connection, collection, parseValueOrValueArray(tenants).map(Serialize.tenantsCreate))
49+
.do()
50+
.then((res) => res.map(parseTenantREST)),
4851
get: async function () {
4952
const check = await dbVersionSupport.supportsTenantsGetGRPCMethod();
5053
return check.supports ? getGRPC() : getREST();
@@ -60,12 +63,10 @@ const tenants = (
6063
collection,
6164
parseValueOrValueArray(tenants).map(parseStringOrTenant)
6265
).do(),
63-
update: (tenants: Tenant | TenantUpdate | (Tenant | TenantUpdate)[]) =>
64-
new TenantsUpdater(
65-
connection,
66-
collection,
67-
parseValueOrValueArray(tenants).map(Serialize.tenantUpdate)
68-
).do() as Promise<Tenant[]>,
66+
update: (tenants: TenantBC | TenantUpdate | (TenantBC | TenantUpdate)[]) =>
67+
new TenantsUpdater(connection, collection, parseValueOrValueArray(tenants).map(Serialize.tenantUpdate))
68+
.do()
69+
.then((res) => res.map(parseTenantREST)),
6970
};
7071
};
7172

@@ -97,10 +98,10 @@ export interface Tenants {
9798
*
9899
* For details on the new activity statuses, see the docstring for the `Tenants` interface type.
99100
*
100-
* @param {Tenant | TenantCreate | (Tenant | TenantCreate)[]} tenants The tenant or tenants to create.
101+
* @param {TenantCreate | TenantCreate[]} tenants The tenant or tenants to create.
101102
* @returns {Promise<Tenant[]>} The created tenant(s) as a list of Tenant.
102103
*/
103-
create: (tenants: Tenant | TenantCreate | (Tenant | TenantCreate)[]) => Promise<Tenant[]>;
104+
create: (tenants: TenantBC | TenantCreate | (TenantBC | TenantCreate)[]) => Promise<Tenant[]>;
104105
/**
105106
* Return all tenants currently associated with a collection in Weaviate.
106107
* The collection must have been created with multi-tenancy enabled.
@@ -152,5 +153,5 @@ export interface Tenants {
152153
* @param {TenantInput | TenantInput[]} tenants The tenant or tenants to update.
153154
* @returns {Promise<Tenant[]>} The updated tenant(s) as a list of Tenant.
154155
*/
155-
update: (tenants: Tenant | TenantUpdate | (Tenant | TenantUpdate)[]) => Promise<Tenant[]>;
156+
update: (tenants: TenantBC | TenantUpdate | (TenantBC | TenantUpdate)[]) => Promise<Tenant[]>;
156157
}

src/collections/tenants/integration.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,23 @@ describe('Testing of the collection.tenants methods', () => {
3838
const result = await collection.tenants.create([{ name: tenant, activityStatus: 'HOT' }]);
3939
expect(result.length).toBe(1);
4040
expect(result[0].name).toBe(tenant);
41-
expect(result[0].activityStatus).toBe('HOT');
41+
expect(result[0].activityStatus).toBe('ACTIVE');
4242
});
4343

4444
it('should be able to create a tenant with new nomenclature', async () => {
4545
const tenant = 'tenant';
4646
const result = await collection.tenants.create([{ name: tenant, activityStatus: 'ACTIVE' }]);
4747
expect(result.length).toBe(1);
4848
expect(result[0].name).toBe(tenant);
49-
expect(result[0].activityStatus).toBe('HOT');
49+
expect(result[0].activityStatus).toBe('ACTIVE');
5050
});
5151

5252
it('should be able to get existing tenants', async () => {
5353
const result = await collection.tenants.get();
5454

5555
expect(result).toHaveProperty('hot');
5656
expect(result.hot.name).toBe('hot');
57-
expect(result.hot.activityStatus).toBe('HOT');
57+
expect(result.hot.activityStatus).toBe('ACTIVE');
5858

5959
expect(result).toHaveProperty('cold');
6060
expect(result.cold.name).toBe('cold');
@@ -72,14 +72,14 @@ describe('Testing of the collection.tenants methods', () => {
7272
const result = await collection.tenants.update([{ name: 'cold', activityStatus: 'HOT' }]);
7373
expect(result.length).toBe(1);
7474
expect(result[0].name).toBe('cold');
75-
expect(result[0].activityStatus).toBe('HOT');
75+
expect(result[0].activityStatus).toBe('ACTIVE');
7676
});
7777

7878
it('should be able to update a tenant with new nomenclature', async () => {
7979
const result = await collection.tenants.update([{ name: 'cold-new', activityStatus: 'ACTIVE' }]);
8080
expect(result.length).toBe(1);
8181
expect(result[0].name).toBe('cold-new');
82-
expect(result[0].activityStatus).toBe('HOT');
82+
expect(result[0].activityStatus).toBe('ACTIVE');
8383
});
8484

8585
describe('getByName and getByNames', () => {
@@ -91,7 +91,7 @@ describe('Testing of the collection.tenants methods', () => {
9191
}
9292
const result = await query();
9393
expect(result).toHaveProperty('name', 'hot');
94-
expect(result).toHaveProperty('activityStatus', 'HOT');
94+
expect(result).toHaveProperty('activityStatus', 'ACTIVE');
9595
});
9696

9797
it('should be able to get a tenant by tenant object', async () => {
@@ -102,7 +102,7 @@ describe('Testing of the collection.tenants methods', () => {
102102
}
103103
const result = await query();
104104
expect(result).toHaveProperty('name', 'hot');
105-
expect(result).toHaveProperty('activityStatus', 'HOT');
105+
expect(result).toHaveProperty('activityStatus', 'ACTIVE');
106106
});
107107

108108
it('should fail to get a non-existing tenant', async () => {

src/collections/tenants/types.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,20 @@ export type TenantsGetOptions = {
2323

2424
/**
2525
* The expected type returned by all tenant methods.
26-
*
27-
* WARNING: The `COLD` and `HOT` statuses are deprecated and will be replaced in a future release.
28-
* See the docstring for the `activityStatus` field in this type for more information.
2926
*/
3027
export type Tenant = TenantBase & {
31-
/**
32-
* `COLD` and `HOT` are included for backwards compatability purposes and are deprecated.
33-
*
34-
* In a future release, these will be removed in favour of the new statuses as so:
35-
* - `HOT` -> `ACTIVE`
36-
* - `COLD` -> `INACTIVE`
28+
/** There are two statuses that are immutable: `OFFLOADED` and `ONLOADING, which are set by the server:
29+
* - `ONLOADING`, which means the tenant is transitioning from the `OFFLOADED` status to `ACTIVE/INACTIVE`.
30+
* - `OFFLOADING`, which means the tenant is transitioning from `ACTIVE/INACTIVE` to the `OFFLOADED` status.
31+
* The other three statuses are mutable within the `.create` and `.update`, methods:
32+
* - `ACTIVE`, which means loaded fully into memory and ready for use.
33+
* - `INACTIVE`, which means not loaded into memory with files stored on disk.
34+
* - `OFFLOADED`, which means not loaded into memory with files stored on the cloud.
3735
*/
38-
activityStatus: 'COLD' | 'HOT' | 'OFFLOADED' | 'OFFLOADING' | 'ONLOADING';
36+
activityStatus: 'ACTIVE' | 'INACTIVE' | 'OFFLOADED' | 'OFFLOADING' | 'ONLOADING';
37+
};
38+
39+
/** This is the type of the Tenant as defined in Weaviate's OpenAPI schema. It is included here for Backwards Compatibility. */
40+
export type TenantBC = TenantBase & {
41+
activityStatus?: 'HOT' | 'COLD' | 'FROZEN';
3942
};

src/collections/tenants/unit.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ describe('Mock testing of tenants.get() method with a REST server', () => {
8484
const collection = client.collections.get(TENANTS_COLLECTION_NAME);
8585
const tenants = await collection.tenants.get();
8686
expect(tenants).toEqual<Record<string, Tenant>>({
87-
hot: { name: 'hot', activityStatus: 'HOT' },
88-
cold: { name: 'cold', activityStatus: 'COLD' },
87+
hot: { name: 'hot', activityStatus: 'ACTIVE' },
88+
cold: { name: 'cold', activityStatus: 'INACTIVE' },
8989
frozen: { name: 'frozen', activityStatus: 'OFFLOADED' },
9090
freezing: { name: 'freezing', activityStatus: 'OFFLOADING' },
9191
unfreezing: { name: 'unfreezing', activityStatus: 'ONLOADING' },
@@ -110,8 +110,8 @@ describe('Mock testing of tenants.get() method with a gRPC server', () => {
110110
const collection = client.collections.get(TENANTS_COLLECTION_NAME);
111111
const tenants = await collection.tenants.get();
112112
expect(tenants).toEqual<Record<string, Tenant>>({
113-
hot: { name: 'hot', activityStatus: 'HOT' },
114-
cold: { name: 'cold', activityStatus: 'COLD' },
113+
hot: { name: 'hot', activityStatus: 'ACTIVE' },
114+
cold: { name: 'cold', activityStatus: 'INACTIVE' },
115115
frozen: { name: 'frozen', activityStatus: 'OFFLOADED' },
116116
freezing: { name: 'freezing', activityStatus: 'OFFLOADING' },
117117
unfreezing: { name: 'unfreezing', activityStatus: 'ONLOADING' },

0 commit comments

Comments
 (0)