瀏覽代碼

support db part2

Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>
ruiyi.jiang 1 年之前
父節點
當前提交
bc54159d93

+ 1 - 0
client/public/env-config.js

@@ -2,6 +2,7 @@ window._env_ = {
   MILVUS_URL: '127.0.0.1:19530',
   HOST_URL: '',
   IS_ELECTRON: '{{IS_ELECTRON}}',
+  DATBASE: 'default',
   WITH_PROMETHEUS: '',
   PROMETHEUS_ADDRESS: '',
   PROMETHEUS_INSTANCE_NAME: '',

+ 1 - 0
client/src/consts/Localstorage.ts

@@ -1,6 +1,7 @@
 export const SESSION = 'CLOUD_SESSION';
 export const MILVUS_ADDRESS = 'milvus-address';
 export const LAST_TIME_ADDRESS = 'last-time-address';
+export const LAST_TIME_DATABASE = 'last-time-database';
 
 export const LAST_TIME_WITH_PROMETHEUS = 'last-time-with-prometheus';
 export const LAST_TIME_PROMETHEUS_ADDRESS = 'last-time-prometheus-address';

+ 3 - 0
client/src/consts/Milvus.ts

@@ -1,6 +1,9 @@
 export const MILVUS_URL =
   ((window as any)._env_ && (window as any)._env_.MILVUS_URL) || '';
 
+export const MILVUS_DATABASE =
+  ((window as any)._env_ && (window as any)._env_.DATABASE) || '';
+
 export const DYNAMIC_FIELD = `$meta`;
 
 export enum DataTypeEnum {

+ 5 - 1
client/src/http/Milvus.ts

@@ -20,8 +20,12 @@ export class MilvusHttp extends BaseModel {
     address: string;
     username?: string;
     password?: string;
+    database?: string;
   }) {
-    return super.create({ path: this.CONNECT_URL, data });
+    return super.create({ path: this.CONNECT_URL, data }) as Promise<{
+      address: string;
+      database: string;
+    }>;
   }
 
   static closeConnection() {

+ 23 - 12
client/src/pages/connect/AuthForm.tsx

@@ -9,8 +9,19 @@ import { useFormValidation } from '@/hooks';
 import { formatForm } from '@/utils';
 import { MilvusHttp } from '@/http';
 import { useNavigate } from 'react-router-dom';
-import { rootContext, authContext, prometheusContext } from '@/context';
-import { MILVUS_ADDRESS, LAST_TIME_ADDRESS, MILVUS_URL } from '@/consts';
+import {
+  rootContext,
+  authContext,
+  prometheusContext,
+  dataContext,
+} from '@/context';
+import {
+  MILVUS_ADDRESS,
+  LAST_TIME_ADDRESS,
+  MILVUS_URL,
+  LAST_TIME_DATABASE,
+  MILVUS_DATABASE,
+} from '@/consts';
 import { CustomRadio } from '@/components/customRadio/CustomRadio';
 
 const useStyles = makeStyles((theme: Theme) => ({
@@ -18,7 +29,6 @@ const useStyles = makeStyles((theme: Theme) => ({
     display: 'flex',
     flexDirection: 'column',
     alignItems: 'flex-end',
-
     padding: theme.spacing(0, 3),
   },
   titleWrapper: {
@@ -54,6 +64,7 @@ export const AuthForm = (props: any) => {
 
   const { openSnackBar } = useContext(rootContext);
   const { setAddress, setIsAuth } = useContext(authContext);
+  const { setDatabase } = useContext(dataContext);
 
   const Logo = icons.zilliz;
   const { t: commonTrans } = useTranslation();
@@ -67,7 +78,8 @@ export const AuthForm = (props: any) => {
     address: window.localStorage.getItem(LAST_TIME_ADDRESS) || MILVUS_URL,
     username: '',
     password: '',
-    database: '',
+    database:
+      window.localStorage.getItem(LAST_TIME_DATABASE) || MILVUS_DATABASE,
     ssl: false,
   });
   const checkedForm = useMemo(() => {
@@ -190,19 +202,18 @@ export const AuthForm = (props: any) => {
 
   const handleConnect = async (event: React.FormEvent) => {
     event.preventDefault();
-    const address = form.address;
-    const data = { ...form, address };
-    const d = await MilvusHttp.connect(data);
-
-    console.log(111, d, data)
+    const result = await MilvusHttp.connect(form);
 
     setIsAuth(true);
-    setAddress(address);
+    setAddress(form.address);
+    setDatabase(result.database);
 
     openSnackBar(successTrans('connect'));
-    window.localStorage.setItem(MILVUS_ADDRESS, address);
+    window.localStorage.setItem(MILVUS_ADDRESS, form.address);
     // store address for next time using
-    window.localStorage.setItem(LAST_TIME_ADDRESS, address);
+    window.localStorage.setItem(LAST_TIME_ADDRESS, form.address);
+    window.localStorage.setItem(LAST_TIME_DATABASE, form.database);
+    // redirect to homepage
     navigate('/');
   };
 

+ 4 - 5
client/src/pages/overview/Overview.tsx

@@ -17,7 +17,6 @@ import { LOADING_STATE, MILVUS_DEPLOY_MODE } from '@/consts';
 import { WS_EVENTS, WS_EVENTS_TYPE } from '@server/utils/Const';
 import { useNavigationHook } from '@/hooks';
 import { CollectionHttp, MilvusHttp } from '@/http';
-import { ShowCollectionsType } from '@/types/Milvus';
 import { ALL_ROUTER_TYPES } from '@/router/Types';
 import { checkLoading, checkIndexBuilding, formatNumber } from '@/utils';
 import CollectionCard from './collectionCard/CollectionCard';
@@ -130,6 +129,7 @@ const Overview = () => {
 
   const fetchData = useCallback(async () => {
     setLoading(true);
+    setCollections([]);
     const res = (await CollectionHttp.getStatistics()) as statisticsType;
     const collections = await CollectionHttp.getCollections();
     const hasLoadingOrBuildingCollection = collections.some(
@@ -151,11 +151,10 @@ const Overview = () => {
     fetchData();
   }, [fetchData]);
 
-  const loadCollections = useMemo(
-    () => collections.filter(c => c._status !== LOADING_STATE.UNLOADED),
-    [collections]
+  const loadCollections = collections.filter(
+    c => c._status !== LOADING_STATE.UNLOADED
   );
-
+  console.log('loadCollections', loadCollections);
   const onRelease = () => {
     openSnackBar(
       successTrans('release', { name: collectionTrans('collection') })

+ 1 - 0
client/src/pages/overview/collectionCard/CollectionCard.tsx

@@ -124,6 +124,7 @@ const CollectionCard: FC<CollectionCardProps> = ({
   const fetchData = useCallback(async () => {
     try {
       setLoading(true);
+      console.log(name)
       const data = (await CollectionHttp.count(name)) as CollectionData;
       setCount(data._rowCount);
     } catch (e) {

+ 15 - 15
client/yarn.lock

@@ -746,10 +746,10 @@
     prop-types "^15.7.2"
     reselect "^4.0.0"
 
-"@remix-run/router@1.7.2":
-  version "1.7.2"
-  resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.7.2.tgz#cba1cf0a04bc04cb66027c51fa600e9cbc388bc8"
-  integrity sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==
+"@remix-run/router@1.13.0":
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.0.tgz#7e29c4ee85176d9c08cb0f4456bff74d092c5065"
+  integrity sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA==
 
 "@rollup/pluginutils@^4.1.1":
   version "4.2.1"
@@ -3551,20 +3551,20 @@ react-refresh@^0.14.0:
   resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
   integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
 
-react-router-dom@^6.14.2:
-  version "6.14.2"
-  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.14.2.tgz#88f520118b91aa60233bd08dbd3fdcaea3a68488"
-  integrity sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==
+react-router-dom@^6.20.0:
+  version "6.20.0"
+  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.0.tgz#7b9527a1e29c7fb90736a5f89d54ca01f40e264b"
+  integrity sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ==
   dependencies:
-    "@remix-run/router" "1.7.2"
-    react-router "6.14.2"
+    "@remix-run/router" "1.13.0"
+    react-router "6.20.0"
 
-react-router@6.14.2:
-  version "6.14.2"
-  resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.14.2.tgz#1f60994d8c369de7b8ba7a78d8f7ec23df76b300"
-  integrity sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==
+react-router@6.20.0:
+  version "6.20.0"
+  resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.0.tgz#4275a3567ecc55f7703073158048db10096bb539"
+  integrity sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w==
   dependencies:
-    "@remix-run/router" "1.7.2"
+    "@remix-run/router" "1.13.0"
 
 react-syntax-highlighter@^15.5.0:
   version "15.5.0"

+ 6 - 1
server/src/database/databases.service.ts

@@ -7,7 +7,7 @@ import {
 import { throwErrorFromSDK } from '../utils/Error';
 
 export class DatabasesService {
-  constructor(private milvusService: MilvusService) {}
+  constructor(private milvusService: MilvusService) { }
 
   async createDatabase(data: CreateDatabaseRequest) {
     const res = await this.milvusService.client.createDatabase(data);
@@ -30,4 +30,9 @@ export class DatabasesService {
   async use(db_name: string) {
     return await await MilvusService.activeMilvusClient.use({ db_name });
   }
+
+  async hasDatabase(data: string) {
+    const { db_names } = await this.listDatabase();
+    return db_names.indexOf(data) !== -1;
+  }
 }

+ 4 - 1
server/src/milvus/dto.ts

@@ -1,8 +1,11 @@
-import { ArrayMinSize, IsArray, IsString } from "class-validator";
+import { ArrayMinSize, IsArray, IsOptional, IsString } from "class-validator";
 
 export class ConnectMilvusDto {
   @IsString()
   readonly address: string;
+
+  @IsOptional()
+  readonly database: string;
 }
 
 export class CheckMilvusDto {

+ 2 - 2
server/src/milvus/milvus.controller.ts

@@ -43,11 +43,11 @@ export class MilvusController {
   }
 
   async connectMilvus(req: Request, res: Response, next: NextFunction) {
-    const { address, username, password } = req.body;
+    const { address, username, password, database } = req.body;
     const cache = req.app.get(CACHE_KEY);
     try {
       const result = await this.milvusService.connectMilvus(
-        { address, username, password },
+        { address, username, password, database },
         cache
       );
 

+ 39 - 14
server/src/milvus/milvus.service.ts

@@ -8,6 +8,7 @@ import LruCache from 'lru-cache';
 import { HTTP_STATUS_CODE } from '../utils/Const';
 import { DEFAULT_MILVUS_PORT } from '../utils';
 import { connectivityState } from '@grpc/grpc-js';
+import { DatabasesService } from '../database/databases.service';
 
 export class MilvusService {
   // Share with all instances, so activeAddress is static
@@ -44,39 +45,63 @@ export class MilvusService {
       address: string;
       username?: string;
       password?: string;
+      database?: string;
     },
     cache: LruCache<any, any>
   ) {
-    const { address, username, password } = data;
-    // grpc only need address without http
+    // Destructure the data object to get the connection details
+    const { address, username, password, database } = data;
+
+    // Format the address to remove the http prefix
     const milvusAddress = MilvusService.formatAddress(address);
 
     try {
+      // Create a new Milvus client with the provided connection details
       const milvusClient: MilvusClient = new MilvusClient({
         address: milvusAddress,
         username,
         password,
       });
 
-      // don't break attu
-      await milvusClient.connectPromise.catch(error => {
-        throw HttpErrors(HTTP_STATUS_CODE.FORBIDDEN, error);
-      });
+      // Set the active Milvus client to the newly created client
+      MilvusService.activeMilvusClient = milvusClient;
 
-      // check healthy
+      try {
+        // Attempt to connect to the Milvus server
+        await milvusClient.connectPromise;
+      } catch (error) {
+        // If the connection fails, clear the cache and throw an error
+        cache.dump();
+        throw new Error('Failed to connect to Milvus: ' + error);
+      }
+
+      // Check the health of the Milvus server
       const res = await milvusClient.checkHealth();
 
-      if (res.isHealthy) {
-        MilvusService.activeAddress = address;
-        cache.set(address, milvusClient);
-        return { address };
-      } else {
+      // If the server is not healthy, throw an error
+      if (!res.isHealthy) {
         throw new Error('Milvus is not ready yet.');
       }
+
+      // If the server is healthy, set the active address and add the client to the cache
+      MilvusService.activeAddress = address;
+      cache.set(address, milvusClient);
+
+      // Create a new database service and check if the specified database exists
+      const databaseService = new DatabasesService(this);
+      const hasDatabase = await databaseService.hasDatabase(database);
+
+      // if database exists, use this db
+      if (hasDatabase) {
+        await databaseService.use(database);
+      }
+
+      // Return the address and the database (if it exists, otherwise return 'default')
+      return { address, database: hasDatabase ? database : 'default' };
     } catch (error) {
-      // if milvus is not working, delete connection.
+      // If any error occurs, clear the cache and throw the error
       cache.dump();
-      throw HttpErrors(HTTP_STATUS_CODE.FORBIDDEN, error);
+      throw error;
     }
   }