2828import lombok .AccessLevel ;
2929import lombok .Getter ;
3030import lombok .extern .slf4j .Slf4j ;
31+
32+ import org .apache .skywalking .banyandb .common .v1 .BanyandbCommon ;
3133import org .apache .skywalking .banyandb .measure .v1 .BanyandbMeasure ;
3234import org .apache .skywalking .banyandb .measure .v1 .MeasureServiceGrpc ;
3335import org .apache .skywalking .banyandb .stream .v1 .BanyandbStream ;
3638import org .apache .skywalking .banyandb .v1 .client .grpc .channel .ChannelManager ;
3739import org .apache .skywalking .banyandb .v1 .client .grpc .channel .DefaultChannelFactory ;
3840import org .apache .skywalking .banyandb .v1 .client .grpc .exception .BanyanDBException ;
41+ import org .apache .skywalking .banyandb .v1 .client .grpc .exception .InternalException ;
42+ import org .apache .skywalking .banyandb .v1 .client .grpc .exception .InvalidArgumentException ;
3943import org .apache .skywalking .banyandb .v1 .client .metadata .Group ;
4044import org .apache .skywalking .banyandb .v1 .client .metadata .GroupMetadataRegistry ;
4145import org .apache .skywalking .banyandb .v1 .client .metadata .IndexRule ;
5862import java .util .ArrayList ;
5963import java .util .Collections ;
6064import java .util .List ;
65+ import java .util .concurrent .CompletableFuture ;
6166import java .util .concurrent .TimeUnit ;
6267import java .util .concurrent .locks .ReentrantLock ;
6368import java .util .stream .Collectors ;
@@ -198,33 +203,73 @@ void connect(Channel channel) {
198203 * Perform a single write with given entity.
199204 *
200205 * @param streamWrite the entity to be written
206+ * @return a future of write result
201207 */
202- public void write (StreamWrite streamWrite ) {
208+ public CompletableFuture < Void > write (StreamWrite streamWrite ) {
203209 checkState (this .streamServiceStub != null , "stream service is null" );
204210
211+ CompletableFuture <Void > future = new CompletableFuture <>();
205212 final StreamObserver <BanyandbStream .WriteRequest > writeRequestStreamObserver
206213 = this .streamServiceStub
207214 .withDeadlineAfter (this .getOptions ().getDeadline (), TimeUnit .SECONDS )
208215 .write (
209216 new StreamObserver <BanyandbStream .WriteResponse >() {
217+ private BanyanDBException responseException ;
218+
210219 @ Override
211220 public void onNext (BanyandbStream .WriteResponse writeResponse ) {
221+ switch (writeResponse .getStatus ()) {
222+ case STATUS_INVALID_TIMESTAMP :
223+ responseException = new InvalidArgumentException (
224+ "Invalid timestamp: " + streamWrite .getTimestamp (), null , Status .Code .INVALID_ARGUMENT , false );
225+ break ;
226+ case STATUS_NOT_FOUND :
227+ responseException = new InvalidArgumentException (
228+ "Invalid metadata: " + streamWrite .entityMetadata , null , Status .Code .INVALID_ARGUMENT , false );
229+ break ;
230+ case STATUS_EXPIRED_SCHEMA :
231+ BanyandbCommon .Metadata metadata = writeResponse .getMetadata ();
232+ log .warn ("The schema {}.{} is expired, trying update the schema..." ,
233+ metadata .getGroup (), metadata .getName ());
234+ try {
235+ BanyanDBClient .this .findStream (metadata .getGroup (), metadata .getName ());
236+ } catch (BanyanDBException e ) {
237+ String warnMessage = String .format ("Failed to refresh the stream schema %s.%s" ,
238+ metadata .getGroup (), metadata .getName ());
239+ log .warn (warnMessage , e );
240+ }
241+ responseException = new InvalidArgumentException (
242+ "Expired revision: " + metadata .getModRevision (), null , Status .Code .INVALID_ARGUMENT , true );
243+ break ;
244+ case STATUS_INTERNAL_ERROR :
245+ responseException = new InternalException (
246+ "Internal error occurs in server" , null , Status .Code .INTERNAL , true );
247+ break ;
248+ default :
249+ }
212250 }
213251
214252 @ Override
215253 public void onError (Throwable throwable ) {
216254 log .error ("Error occurs in flushing streams." , throwable );
255+ future .completeExceptionally (throwable );
217256 }
218257
219258 @ Override
220259 public void onCompleted () {
260+ if (responseException == null ) {
261+ future .complete (null );
262+ } else {
263+ future .completeExceptionally (responseException );
264+ }
221265 }
222266 });
223267 try {
224268 writeRequestStreamObserver .onNext (streamWrite .build ());
225269 } finally {
226270 writeRequestStreamObserver .onCompleted ();
227271 }
272+ return future ;
228273 }
229274
230275 /**
@@ -239,7 +284,7 @@ public void onCompleted() {
239284 public StreamBulkWriteProcessor buildStreamWriteProcessor (int maxBulkSize , int flushInterval , int concurrency ) {
240285 checkState (this .streamServiceStub != null , "stream service is null" );
241286
242- return new StreamBulkWriteProcessor (this . streamServiceStub , maxBulkSize , flushInterval , concurrency );
287+ return new StreamBulkWriteProcessor (this , maxBulkSize , flushInterval , concurrency );
243288 }
244289
245290 /**
@@ -254,7 +299,7 @@ public StreamBulkWriteProcessor buildStreamWriteProcessor(int maxBulkSize, int f
254299 public MeasureBulkWriteProcessor buildMeasureWriteProcessor (int maxBulkSize , int flushInterval , int concurrency ) {
255300 checkState (this .measureServiceStub != null , "measure service is null" );
256301
257- return new MeasureBulkWriteProcessor (this . measureServiceStub , maxBulkSize , flushInterval , concurrency );
302+ return new MeasureBulkWriteProcessor (this , maxBulkSize , flushInterval , concurrency );
258303 }
259304
260305 /**
@@ -361,23 +406,57 @@ public Group define(Group group) throws BanyanDBException {
361406 */
362407 public void define (Stream stream ) throws BanyanDBException {
363408 StreamMetadataRegistry streamRegistry = new StreamMetadataRegistry (checkNotNull (this .channel ));
364- streamRegistry .create (stream );
409+ long modRevision = streamRegistry .create (stream );
365410 defineIndexRules (stream , stream .indexRules ());
411+
412+ stream = stream .withModRevision (modRevision );
366413 this .metadataCache .register (stream );
367414 }
368415
416+ /**
417+ * Delete a stream
418+ *
419+ * @param stream the stream to be deleted
420+ * @return true if the stream is deleted successfully
421+ */
422+ public boolean delete (Stream stream ) throws BanyanDBException {
423+ StreamMetadataRegistry streamRegistry = new StreamMetadataRegistry (checkNotNull (this .channel ));
424+ if (streamRegistry .delete (stream .group (), stream .name ())) {
425+ this .metadataCache .unregister (stream );
426+ return true ;
427+ }
428+ return false ;
429+ }
430+
369431 /**
370432 * Define a new measure
371433 *
372434 * @param measure the measure to be created
373435 */
374436 public void define (Measure measure ) throws BanyanDBException {
375437 MeasureMetadataRegistry measureRegistry = new MeasureMetadataRegistry (checkNotNull (this .channel ));
376- measureRegistry .create (measure );
438+ long modRevision = measureRegistry .create (measure );
377439 defineIndexRules (measure , measure .indexRules ());
440+
441+ measure = measure .withModRevision (modRevision );
378442 this .metadataCache .register (measure );
379443 }
380444
445+ /**
446+ * Delete a measure
447+ *
448+ * @param measure the measure to be deleted
449+ * @return true if the measure is deleted successfully
450+ */
451+ public boolean delete (Measure measure ) throws BanyanDBException {
452+ MeasureMetadataRegistry measureRegistry = new MeasureMetadataRegistry (checkNotNull (this .channel ));
453+ if (measureRegistry .delete (measure .group (), measure .name ())) {
454+ this .metadataCache .unregister (measure );
455+ return true ;
456+ }
457+ return false ;
458+ }
459+
381460 /**
382461 * Define a new TopNAggregation
383462 *
0 commit comments