11package com .milvus .io .kafka ;
22
3+ import com .alibaba .fastjson .JSONObject ;
34import com .milvus .io .kafka .helper .MilvusClientHelper ;
45import com .milvus .io .kafka .utils .DataConverter ;
56import com .milvus .io .kafka .utils .Utils ;
67import com .milvus .io .kafka .utils .VersionUtil ;
7- import io .milvus .client .MilvusServiceClient ;
8- import io .milvus .grpc .CollectionSchema ;
9- import io .milvus .grpc .DescribeCollectionResponse ;
10- import io .milvus .grpc .GetLoadStateResponse ;
11- import io .milvus .grpc .LoadState ;
12- import io .milvus .param .R ;
13- import io .milvus .param .collection .DescribeCollectionParam ;
14- import io .milvus .param .collection .GetLoadStateParam ;
15- import io .milvus .param .dml .InsertParam ;
8+ import io .milvus .v2 .client .MilvusClientV2 ;
9+ import io .milvus .v2 .service .collection .request .CreateCollectionReq ;
10+ import io .milvus .v2 .service .collection .request .DescribeCollectionReq ;
11+ import io .milvus .v2 .service .collection .request .GetLoadStateReq ;
12+ import io .milvus .v2 .service .collection .request .HasCollectionReq ;
13+ import io .milvus .v2 .service .collection .response .DescribeCollectionResp ;
14+ import io .milvus .v2 .service .vector .request .InsertReq ;
15+ import io .milvus .v2 .service .vector .request .UpsertReq ;
1616import org .apache .kafka .connect .sink .SinkRecord ;
1717import org .apache .kafka .connect .sink .SinkTask ;
1818import org .slf4j .Logger ;
1919import org .slf4j .LoggerFactory ;
2020
21- import java .util .Collection ;
22- import java .util .List ;
23- import java .util .Map ;
21+ import java .util .*;
2422
2523import static com .milvus .io .kafka .MilvusSinkConnectorConfig .TOKEN ;
2624
2725public class MilvusSinkTask extends SinkTask {
2826
2927 private static final Logger log = LoggerFactory .getLogger (MilvusSinkTask .class );
3028 private MilvusSinkConnectorConfig config ;
31- private MilvusServiceClient myMilvusClient ;
29+ private MilvusClientV2 myMilvusClient ;
3230 private DataConverter converter ;
33- private CollectionSchema collectionSchema ;
31+ private DescribeCollectionResp response ;
3432
3533 @ Override
3634 public String version () {
@@ -43,64 +41,80 @@ public void start(Map<String, String> props) {
4341 }
4442
4543 // make visible for test
46- protected void start (Map <String , String > props , MilvusServiceClient milvusClient ) {
44+ protected void start (Map <String , String > props , MilvusClientV2 milvusClient ) {
4745 log .info ("Starting MilvusSinkTask." );
4846 props .put (TOKEN , Utils .encryptToken (props .get (TOKEN )));
4947 this .config = new MilvusSinkConnectorConfig (props );
5048 this .converter = new DataConverter (config );
5149 this .myMilvusClient = milvusClient == null ? new MilvusClientHelper ().createMilvusClient (config ) : milvusClient ;
52- this .collectionSchema = GetCollectionInfo (config .getCollectionName ());
53-
5450 log .info ("Started MilvusSinkTask, Connecting to Zilliz Cluster:" + config .getUrl ());
51+ preValidate ();
52+ }
5553
54+ private void preValidate () {
55+ // check if the collection exists
56+ if (!myMilvusClient .hasCollection (HasCollectionReq .builder ().collectionName (config .getCollectionName ()).build ())) {
57+ log .error ("Collection not exist" );
58+ throw new RuntimeException ("Collection not exist" + config .getCollectionName ());
59+ }
60+ // check if the collection is loaded
61+ if (!myMilvusClient .getLoadState (GetLoadStateReq .builder ().collectionName (config .getCollectionName ()).build ())){
62+ log .error ("Collection not loaded" );
63+ throw new RuntimeException ("Collection not loaded" + config .getCollectionName ());
64+ }
65+ this .response = myMilvusClient .describeCollection (DescribeCollectionReq .builder ().collectionName (config .getCollectionName ()).build ());
5666 }
5767
5868 @ Override
5969 public void put (Collection <SinkRecord > records ) {
6070 log .info ("Putting {} records to Milvus." , records .size ());
71+ if (records .isEmpty ()) {
72+ log .info ("No records to put." );
73+ return ;
74+ }
6175
76+ // not support dynamic schema for now, for dynamic schema, we need to put the data into a JSONObject
77+ List <JSONObject > datas = new ArrayList <>();
6278 for (SinkRecord record : records ) {
6379 log .debug ("Writing {} to Milvus." , record );
64- WriteRecord (record , collectionSchema );
80+ if (record .value () == null ) {
81+ log .warn ("Skipping record with null value." );
82+ continue ;
83+ }
84+ try {
85+ JSONObject data = converter .convertRecord (record , response .getCollectionSchema ());
86+ datas .add (data );
87+ }catch (Exception e ){
88+ log .error ("Failed to convert record to JSONObject, skip it" , e );
89+ }
6590 }
66- }
6791
68- protected CollectionSchema GetCollectionInfo (String collectionName ) {
69- // check if the collection exists
70- R <DescribeCollectionResponse > response = myMilvusClient .describeCollection (DescribeCollectionParam .newBuilder ()
71- .withCollectionName (collectionName ).build ());
72- if (response .getData () == null ) {
73- log .error ("Collection not exist" );
74- throw new RuntimeException ("Collection not exist" + collectionName );
92+ if (!response .getAutoID ()){
93+ // default to use upsert
94+ UpsertReq upsertReq = UpsertReq .builder ()
95+ .collectionName (config .getCollectionName ())
96+ .data (datas )
97+ .build ();
98+ log .info ("Upserting data to collection: {} with datas: {}" , config .getCollectionName (), datas );
99+ myMilvusClient .upsert (upsertReq );
75100 }else {
76- GetLoadStateParam getLoadStateParam = GetLoadStateParam .newBuilder ()
77- .withCollectionName (collectionName )
101+ InsertReq insertReq = InsertReq .builder ()
102+ .collectionName (config .getCollectionName ())
103+ .data (datas )
78104 .build ();
79- R <GetLoadStateResponse > loadState = myMilvusClient .getLoadState (getLoadStateParam );
80- if (loadState .getData ().getState () != LoadState .LoadStateLoaded ){
81- log .error ("Collection not loaded" );
82- throw new RuntimeException ("Collection not loaded" + collectionName );
83- }
105+ log .info ("Inserting data to collection: {} with fields: {}" , config .getCollectionName (), datas .get (0 ).keySet ());
106+ myMilvusClient .insert (insertReq );
84107 }
85- return response .getData ().getSchema ();
86- }
87108
88- protected void WriteRecord (SinkRecord record , CollectionSchema collectionSchema ) {
89- // not support dynamic schema for now, for dynamic schema, we need to put the data into a JSONObject
90- List <InsertParam .Field > fields = converter .convertRecord (record , collectionSchema );
91- InsertParam insertParam = InsertParam .newBuilder ()
92- .withCollectionName (config .getCollectionName ())
93- .withFields (fields )
94- .build ();
95-
96- log .info ("Inserting data to collection: " + config .getCollectionName () + " with fields: " +
97- insertParam .getFields ());
98- myMilvusClient .insert (insertParam );
99109 }
100110
101111 @ Override
102112 public void stop () {
103113 log .info ("Stopping Milvus client." );
104- myMilvusClient .close ();
114+ try {
115+ myMilvusClient .close (3 );
116+ } catch (InterruptedException e ) {
117+ throw new RuntimeException (e );
118+ }
105119 }
106120}
0 commit comments