All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.skywalking.banyandb.v1.client.BanyanDBClient Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.apache.skywalking.banyandb.v1.client;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.protobuf.Timestamp;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.Status;
import io.grpc.stub.StreamObserver;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.banyandb.common.v1.BanyandbCommon;
import org.apache.skywalking.banyandb.common.v1.BanyandbCommon.Group;
import org.apache.skywalking.banyandb.common.v1.BanyandbCommon.Metadata;
import org.apache.skywalking.banyandb.database.v1.BanyandbDatabase.TopNAggregation;
import org.apache.skywalking.banyandb.database.v1.BanyandbDatabase.Measure;
import org.apache.skywalking.banyandb.database.v1.BanyandbDatabase.Stream;
import org.apache.skywalking.banyandb.database.v1.BanyandbDatabase.IndexRule;
import org.apache.skywalking.banyandb.database.v1.BanyandbDatabase.IndexRuleBinding;
import org.apache.skywalking.banyandb.database.v1.BanyandbDatabase.Subject;
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty;
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty.Property;
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty.ApplyRequest.Strategy;
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty.ApplyResponse;
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty.DeleteResponse;
import org.apache.skywalking.banyandb.measure.v1.BanyandbMeasure;
import org.apache.skywalking.banyandb.measure.v1.MeasureServiceGrpc;
import org.apache.skywalking.banyandb.stream.v1.BanyandbStream;
import org.apache.skywalking.banyandb.stream.v1.StreamServiceGrpc;
import org.apache.skywalking.banyandb.v1.client.grpc.HandleExceptionsWith;
import org.apache.skywalking.banyandb.v1.client.grpc.channel.ChannelManager;
import org.apache.skywalking.banyandb.v1.client.grpc.channel.DefaultChannelFactory;
import org.apache.skywalking.banyandb.v1.client.grpc.exception.BanyanDBException;
import org.apache.skywalking.banyandb.v1.client.grpc.exception.InternalException;
import org.apache.skywalking.banyandb.v1.client.grpc.exception.InvalidArgumentException;
import org.apache.skywalking.banyandb.v1.client.metadata.GroupMetadataRegistry;
import org.apache.skywalking.banyandb.v1.client.metadata.IndexRuleBindingMetadataRegistry;
import org.apache.skywalking.banyandb.v1.client.metadata.IndexRuleMetadataRegistry;
import org.apache.skywalking.banyandb.v1.client.metadata.MeasureMetadataRegistry;
import org.apache.skywalking.banyandb.v1.client.metadata.MetadataCache;
import org.apache.skywalking.banyandb.v1.client.metadata.PropertyStore;
import org.apache.skywalking.banyandb.v1.client.metadata.ResourceExist;
import org.apache.skywalking.banyandb.v1.client.metadata.StreamMetadataRegistry;
import org.apache.skywalking.banyandb.v1.client.metadata.TopNAggregationMetadataRegistry;

import java.io.Closeable;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.apache.skywalking.banyandb.v1.client.util.TimeUtils;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * BanyanDBClient represents a client instance interacting with BanyanDB server.
 * This is built on the top of BanyanDB v1 gRPC APIs.
 *
 * 
{@code
 * // use `default` group
 * client = new BanyanDBClient("127.0.0.1", 17912);
 * // to send any request, a connection to the server must be estabilished
 * client.connect();
 * }
*/ @Slf4j public class BanyanDBClient implements Closeable { public static final ZonedDateTime DEFAULT_EXPIRE_AT = ZonedDateTime.of(2099, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); private final String[] targets; /** * Options for server connection. */ @Getter(value = AccessLevel.PACKAGE) private final Options options; /** * gRPC connection. */ @Getter(value = AccessLevel.PACKAGE) private volatile Channel channel; /** * gRPC client stub */ @Getter(value = AccessLevel.PACKAGE) private StreamServiceGrpc.StreamServiceStub streamServiceStub; /** * gRPC client stub */ @Getter(value = AccessLevel.PACKAGE) private MeasureServiceGrpc.MeasureServiceStub measureServiceStub; /** * gRPC future stub. */ @Getter(value = AccessLevel.PACKAGE) private StreamServiceGrpc.StreamServiceBlockingStub streamServiceBlockingStub; /** * gRPC future stub. */ @Getter(value = AccessLevel.PACKAGE) private MeasureServiceGrpc.MeasureServiceBlockingStub measureServiceBlockingStub; /** * The connection status. */ private volatile boolean isConnected = false; /** * A lock to control the race condition in establishing and disconnecting network connection. */ private final ReentrantLock connectionEstablishLock; /** * Client local metadata cache. */ private final MetadataCache metadataCache; /** * Create a BanyanDB client instance with a default options. * * @param targets server targets */ public BanyanDBClient(String... targets) { this(targets, new Options()); } /** * Create a BanyanDB client instance with a customized options. * * @param targets server targets * @param options customized options */ public BanyanDBClient(String[] targets, Options options) { String[] tt = Preconditions.checkNotNull(targets, "targets"); checkState(tt.length > 0, "targets' size must be more than 1"); tt = Arrays.stream(tt).filter(t -> !Strings.isNullOrEmpty(t)).toArray(size -> new String[size]); checkState(tt.length > 0, "valid targets' size must be more than 1"); this.targets = tt; this.options = options; this.connectionEstablishLock = new ReentrantLock(); this.metadataCache = new MetadataCache(this); } /** * Construct a connection to the server. * * @throws IOException thrown if fail to create a connection */ public void connect() throws IOException { connectionEstablishLock.lock(); try { if (!isConnected) { URI[] addresses = new URI[this.targets.length]; for (int i = 0; i < this.targets.length; i++) { addresses[i] = URI.create("//" + this.targets[i]); } this.channel = ChannelManager.create(this.options.buildChannelManagerSettings(), new DefaultChannelFactory(addresses, this.options)); streamServiceBlockingStub = StreamServiceGrpc.newBlockingStub(this.channel); measureServiceBlockingStub = MeasureServiceGrpc.newBlockingStub(this.channel); streamServiceStub = StreamServiceGrpc.newStub(this.channel); measureServiceStub = MeasureServiceGrpc.newStub(this.channel); isConnected = true; } } finally { connectionEstablishLock.unlock(); } } @VisibleForTesting void connect(Channel channel) { connectionEstablishLock.lock(); try { if (!isConnected) { this.channel = channel; streamServiceBlockingStub = StreamServiceGrpc.newBlockingStub(this.channel); measureServiceBlockingStub = MeasureServiceGrpc.newBlockingStub(this.channel); streamServiceStub = StreamServiceGrpc.newStub(this.channel); measureServiceStub = MeasureServiceGrpc.newStub(this.channel); isConnected = true; } } finally { connectionEstablishLock.unlock(); } } /** * Perform a single write with given entity. * * @param streamWrite the entity to be written * @return a future of write result */ public CompletableFuture write(StreamWrite streamWrite) { checkState(this.streamServiceStub != null, "stream service is null"); CompletableFuture future = new CompletableFuture<>(); final StreamObserver writeRequestStreamObserver = this.streamServiceStub .withDeadlineAfter(this.getOptions().getDeadline(), TimeUnit.SECONDS) .write( new StreamObserver() { private BanyanDBException responseException; @Override public void onNext(BanyandbStream.WriteResponse writeResponse) { switch (writeResponse.getStatus()) { case STATUS_INVALID_TIMESTAMP: responseException = new InvalidArgumentException( "Invalid timestamp: " + streamWrite.getTimestamp(), null, Status.Code.INVALID_ARGUMENT, false); break; case STATUS_NOT_FOUND: responseException = new InvalidArgumentException( "Invalid metadata: " + streamWrite.entityMetadata, null, Status.Code.INVALID_ARGUMENT, false); break; case STATUS_EXPIRED_SCHEMA: BanyandbCommon.Metadata metadata = writeResponse.getMetadata(); log.warn("The schema {}.{} is expired, trying update the schema...", metadata.getGroup(), metadata.getName()); try { BanyanDBClient.this.updateStreamMetadataCacheFromSever(metadata.getGroup(), metadata.getName()); } catch (BanyanDBException e) { String warnMessage = String.format("Failed to refresh the stream schema %s.%s", metadata.getGroup(), metadata.getName()); log.warn(warnMessage, e); } responseException = new InvalidArgumentException( "Expired revision: " + metadata.getModRevision(), null, Status.Code.INVALID_ARGUMENT, true); break; case STATUS_INTERNAL_ERROR: responseException = new InternalException( "Internal error occurs in server", null, Status.Code.INTERNAL, true); break; default: } } @Override public void onError(Throwable throwable) { log.error("Error occurs in flushing streams.", throwable); future.completeExceptionally(throwable); } @Override public void onCompleted() { if (responseException == null) { future.complete(null); } else { future.completeExceptionally(responseException); } } }); try { writeRequestStreamObserver.onNext(streamWrite.build()); } finally { writeRequestStreamObserver.onCompleted(); } return future; } /** * Create a build process for stream write. * * @param maxBulkSize the max bulk size for the flush operation * @param flushInterval if given maxBulkSize is not reached in this period, the flush would be trigger * automatically. Unit is second * @param concurrency the number of concurrency would run for the flush max * @param timeout network timeout threshold in seconds. * @return stream bulk write processor */ public StreamBulkWriteProcessor buildStreamWriteProcessor(int maxBulkSize, int flushInterval, int concurrency, int timeout) { checkState(this.streamServiceStub != null, "stream service is null"); return new StreamBulkWriteProcessor(this, maxBulkSize, flushInterval, concurrency, timeout); } /** * Create a build process for measure write. * * @param maxBulkSize the max bulk size for the flush operation * @param flushInterval if given maxBulkSize is not reached in this period, the flush would be trigger * automatically. Unit is second * @param concurrency the number of concurrency would run for the flush max * @param timeout network timeout threshold in seconds. * @return stream bulk write processor */ public MeasureBulkWriteProcessor buildMeasureWriteProcessor(int maxBulkSize, int flushInterval, int concurrency, int timeout) { checkState(this.measureServiceStub != null, "measure service is null"); return new MeasureBulkWriteProcessor(this, maxBulkSize, flushInterval, concurrency, timeout); } /** * Build a MeasureWrite request. * * @param group the group of the measure * @param name the name of the measure * @param timestamp the timestamp of the measure * @return the request to be built */ public MeasureWrite createMeasureWrite(String group, String name, long timestamp) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return new MeasureWrite(this.metadataCache.findMeasureMetadata(group, name), timestamp); } /** * Build a StreamWrite request. * * @param group the group of the stream * @param name the name of the stream * @param elementId the primary key of the stream * @return the request to be built */ public StreamWrite createStreamWrite(String group, String name, final String elementId) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return new StreamWrite(this.metadataCache.findStreamMetadata(group, name), elementId); } /** * Build a StreamWrite request. * * @param group the group of the stream * @param name the name of the stream * @param elementId the primary key of the stream * @param timestamp the timestamp of the stream * @return the request to be built */ public StreamWrite createStreamWrite(String group, String name, final String elementId, long timestamp) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return new StreamWrite(this.metadataCache.findStreamMetadata(group, name), elementId, timestamp); } /** * Query streams according to given conditions * * @param streamQuery condition for query * @return hint streams. */ public StreamQueryResponse query(StreamQuery streamQuery) throws BanyanDBException { checkState(this.streamServiceStub != null, "stream service is null"); for (String group : streamQuery.groups) { MetadataCache.EntityMetadata em = this.metadataCache.findStreamMetadata(group, streamQuery.name); if (em != null) { final BanyandbStream.QueryResponse response = HandleExceptionsWith.callAndTranslateApiException(() -> this.streamServiceBlockingStub .withDeadlineAfter(this.getOptions().getDeadline(), TimeUnit.SECONDS) .query(streamQuery.build(em))); return new StreamQueryResponse(response); } } throw new RuntimeException("No metadata found for the query"); } /** * Query TopN according to given conditions * * @param topNQuery condition for query * @return hint topN. */ public TopNQueryResponse query(TopNQuery topNQuery) throws BanyanDBException { checkState(this.measureServiceStub != null, "measure service is null"); final BanyandbMeasure.TopNResponse response = HandleExceptionsWith.callAndTranslateApiException(() -> this.measureServiceBlockingStub .withDeadlineAfter(this.getOptions().getDeadline(), TimeUnit.SECONDS) .topN(topNQuery.build())); return new TopNQueryResponse(response); } /** * Query measures according to given conditions * * @param measureQuery condition for query * @return hint measures. */ public MeasureQueryResponse query(MeasureQuery measureQuery) throws BanyanDBException { checkState(this.streamServiceStub != null, "measure service is null"); for (String group : measureQuery.groups) { MetadataCache.EntityMetadata em = this.metadataCache.findMeasureMetadata(group, measureQuery.name); if (em != null) { final BanyandbMeasure.QueryResponse response = HandleExceptionsWith.callAndTranslateApiException(() -> this.measureServiceBlockingStub .withDeadlineAfter(this.getOptions().getDeadline(), TimeUnit.SECONDS) .query(measureQuery.build(em))); return new MeasureQueryResponse(response); } } throw new RuntimeException("No metadata found for the query"); } /** * Define a new group and attach to the current client. * * @param group the group to be created * @return a grouped client */ public Group define(Group group) throws BanyanDBException { GroupMetadataRegistry registry = new GroupMetadataRegistry(checkNotNull(this.channel)); registry.create(group); return registry.get(null, group.getMetadata().getName()); } /** * Define a new stream * * @param stream the stream to be created */ public void define(Stream stream) throws BanyanDBException { StreamMetadataRegistry streamRegistry = new StreamMetadataRegistry(checkNotNull(this.channel)); long modRevision = streamRegistry.create(stream); stream = stream.toBuilder().setMetadata(stream.getMetadata().toBuilder().setModRevision(modRevision)).build(); this.metadataCache.register(stream); } /** * Define a new stream with index rules, * @param stream the stream to be created * @param indexRules the index rules to be created */ public void define(Stream stream, List indexRules) throws BanyanDBException { define(stream); defineIndexRules(stream, indexRules); } /** * Define a new measure * * @param measure the measure to be created */ public void define(Measure measure) throws BanyanDBException { MeasureMetadataRegistry measureRegistry = new MeasureMetadataRegistry(checkNotNull(this.channel)); long modRevision = measureRegistry.create(measure); measure = measure.toBuilder().setMetadata(measure.getMetadata().toBuilder().setModRevision(modRevision)).build(); this.metadataCache.register(measure); } /** * Define a new measure with index rules * @param measure the measure to be created * @param indexRules the index rules to be created */ public void define(Measure measure, List indexRules) throws BanyanDBException { define(measure); defineIndexRules(measure, indexRules); } /** * Define a new TopNAggregation * * @param topNAggregation the topN rule to be created */ public void define(TopNAggregation topNAggregation) throws BanyanDBException { TopNAggregationMetadataRegistry registry = new TopNAggregationMetadataRegistry(checkNotNull(this.channel)); registry.create(topNAggregation); } /** * Define a new IndexRule * @param indexRule the index rule to be created */ public void define(IndexRule indexRule) throws BanyanDBException { IndexRuleMetadataRegistry registry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); registry.create(indexRule); } /** * Define a new IndexRuleBinding, if the beginAt and expireAt are not set, the default value will be used. * The default value of beginAt is the current time, and the default value of expireAt is 2099-01-01 00:00:00 UTC. * @param indexRuleBinding the index rule binding to be created */ public void define(IndexRuleBinding indexRuleBinding) throws BanyanDBException { ZonedDateTime beginAt = indexRuleBinding.getBeginAt() == Timestamp.getDefaultInstance() ? ZonedDateTime.now() : TimeUtils.parseTimestamp(indexRuleBinding.getBeginAt()); ZonedDateTime expireAt = indexRuleBinding.getExpireAt() == Timestamp.getDefaultInstance() ? DEFAULT_EXPIRE_AT : TimeUtils.parseTimestamp(indexRuleBinding.getExpireAt()); this.define(indexRuleBinding, beginAt, expireAt); } /** * Define a new IndexRuleBinding * @param indexRuleBinding the index rule binding to be created * @param beginAt the beginning time of the index rule binding * @param expireAt the expiry time of the index rule binding */ public void define(IndexRuleBinding indexRuleBinding, ZonedDateTime beginAt, ZonedDateTime expireAt) throws BanyanDBException { IndexRuleBindingMetadataRegistry registry = new IndexRuleBindingMetadataRegistry(checkNotNull(this.channel)); indexRuleBinding = indexRuleBinding.toBuilder() .setBeginAt(TimeUtils.buildTimestamp(beginAt)) .setExpireAt(TimeUtils.buildTimestamp(expireAt)) .build(); registry.create(indexRuleBinding); } /** * Bind index rule to the stream * By default, the index rule binding will be active from now, and it will never be expired. * @param stream the subject of index rule binding * @param indexRules rules to be bounded */ public void defineIndexRules(Stream stream, List indexRules) throws BanyanDBException { Preconditions.checkArgument(stream != null, "stream cannot be null"); IndexRuleMetadataRegistry irRegistry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); for (final IndexRule ir : indexRules) { try { irRegistry.create(ir); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.ALREADY_EXISTS)) { continue; } throw ex; } } if (indexRules.isEmpty()) { return; } List indexRuleNames = indexRules.stream() .map(indexRule -> indexRule.getMetadata().getName()) .collect(Collectors.toList()); IndexRuleBinding binding = IndexRuleBinding.newBuilder() .setMetadata(Metadata.newBuilder() .setGroup( stream.getMetadata().getGroup()) .setName( stream.getMetadata().getName())) .setSubject(Subject.newBuilder() .setName(stream.getMetadata() .getName()) .setCatalog( BanyandbCommon.Catalog.CATALOG_STREAM)) .addAllRules(indexRuleNames).build(); this.define(binding); } /** * Bind index rule to the measure. * By default, the index rule binding will be active from now, and it will never be expired. * * @param measure the subject of index rule binding * @param indexRules rules to be bounded */ public void defineIndexRules(Measure measure, List indexRules) throws BanyanDBException { Preconditions.checkArgument(measure != null, "measure cannot be null"); IndexRuleMetadataRegistry irRegistry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); for (final IndexRule ir : indexRules) { try { irRegistry.create(ir); } catch (BanyanDBException ex) { // multiple entity can share a single index rule if (ex.getStatus().equals(Status.Code.ALREADY_EXISTS)) { continue; } throw ex; } } if (indexRules.isEmpty()) { return; } List indexRuleNames = indexRules.stream().map(indexRule -> indexRule.getMetadata().getName()).collect(Collectors.toList()); IndexRuleBinding binding = IndexRuleBinding.newBuilder() .setMetadata(Metadata.newBuilder() .setGroup( measure.getMetadata().getGroup()) .setName( measure.getMetadata().getName())) .setSubject(Subject.newBuilder() .setName(measure.getMetadata() .getName()) .setCatalog( BanyandbCommon.Catalog.CATALOG_MEASURE)) .addAllRules(indexRuleNames).build(); this.define(binding); } /** * Update the group * * @param group the group to be updated */ public void update(Group group) throws BanyanDBException { GroupMetadataRegistry registry = new GroupMetadataRegistry(checkNotNull(this.channel)); registry.update(group); } /** * Update the stream * @param stream the stream to be updated */ public void update(Stream stream) throws BanyanDBException { StreamMetadataRegistry streamRegistry = new StreamMetadataRegistry(checkNotNull(this.channel)); streamRegistry.update(stream); this.metadataCache.register(stream); } /** * Update the measure * * @param measure the measure to be updated */ public void update(Measure measure) throws BanyanDBException { MeasureMetadataRegistry measureRegistry = new MeasureMetadataRegistry(checkNotNull(this.channel)); measureRegistry.update(measure); this.metadataCache.register(measure); } /** * Update the TopNAggregation * @param topNAggregation the topN rule to be updated */ public void update(TopNAggregation topNAggregation) throws BanyanDBException { TopNAggregationMetadataRegistry registry = new TopNAggregationMetadataRegistry(checkNotNull(this.channel)); registry.update(topNAggregation); } /** * Update the IndexRule * @param indexRule the index rule to be updated */ public void update(IndexRule indexRule) throws BanyanDBException { IndexRuleMetadataRegistry registry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); registry.update(indexRule); } /** * Update the IndexRuleBinding * @param indexRuleBinding the index rule binding to be updated */ public void update(IndexRuleBinding indexRuleBinding) throws BanyanDBException { IndexRuleBindingMetadataRegistry registry = new IndexRuleBindingMetadataRegistry(checkNotNull(this.channel)); registry.update(indexRuleBinding); } /** * Delete the group * @param name name of the group * @return true if the group is deleted successfully */ public boolean deleteGroup(String name) throws BanyanDBException { GroupMetadataRegistry registry = new GroupMetadataRegistry(checkNotNull(this.channel)); return registry.delete(name, name); } /** * Delete a stream * @param group the group name of the stream * @param name the name of the stream * @return true if the stream is deleted successfully */ public boolean deleteStream(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); StreamMetadataRegistry streamRegistry = new StreamMetadataRegistry(checkNotNull(this.channel)); if (streamRegistry.delete(group, name)) { this.metadataCache.unregister(group, name); return true; } return false; } /** * Delete a measure * @param group the group name of the measure * @param name the name of the measure * @return true if the measure is deleted successfully */ public boolean deleteMeasure(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); MeasureMetadataRegistry measureRegistry = new MeasureMetadataRegistry(checkNotNull(this.channel)); if (measureRegistry.delete(group, name)) { this.metadataCache.unregister(group, name); return true; } return false; } /** * Delete the TopNAggregation * @param group the group name of the topN rule * @param name the name of the topN rule * @return true if the topN rule is deleted successfully */ public boolean deleteTopNAggregation(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); TopNAggregationMetadataRegistry registry = new TopNAggregationMetadataRegistry(checkNotNull(this.channel)); return registry.delete(group, name); } /** * Delete the IndexRule * @param group the group name of the index rule * @param name the name of the index rule * @return true if the index rule is deleted successfully */ public boolean deleteIndexRule(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); IndexRuleMetadataRegistry registry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); return registry.delete(group, name); } /** * Delete the IndexRuleBinding * @param group the group name of the index rule binding * @param name the name of the index rule binding * @return true if the index rule binding is deleted successfully */ public boolean deleteIndexRuleBinding(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); IndexRuleBindingMetadataRegistry registry = new IndexRuleBindingMetadataRegistry(checkNotNull(this.channel)); return registry.delete(group, name); } /** * Find the IndexRule * @param group the group name of the index rule * @param name the name of the index rule * @return the index rule if it can be found, otherwise null */ public IndexRule findIndexRule(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); IndexRuleMetadataRegistry registry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); try { return registry.get(group, name); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * Find all IndexRules in the group * @param group the group name of the index rule * @return all index rules in the group */ public List findIndexRules(String group) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); IndexRuleMetadataRegistry registry = new IndexRuleMetadataRegistry(checkNotNull(this.channel)); return registry.list(group); } /** * Find the IndexRuleBinding * @param group the group name of the index rule binding * @param name the name of the index rule binding * @return the index rule binding if it can be found, otherwise null */ public IndexRuleBinding findIndexRuleBinding(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); IndexRuleBindingMetadataRegistry registry = new IndexRuleBindingMetadataRegistry(checkNotNull(this.channel)); try { return registry.get(group, name); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * Find all IndexRuleBindings in the group * @param group the group name of the index rule binding * @return all index rule bindings in the group */ public List findIndexRuleBindings(String group) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); IndexRuleBindingMetadataRegistry registry = new IndexRuleBindingMetadataRegistry(checkNotNull(this.channel)); return registry.list(group); } /** * Apply(Create or update) the property with {@link BanyandbProperty.ApplyRequest.Strategy#STRATEGY_MERGE} * * @param property the property to be stored in the BanyanBD */ public ApplyResponse apply(Property property) throws BanyanDBException { PropertyStore store = new PropertyStore(checkNotNull(this.channel)); return store.apply(property); } /** * Apply(Create or update) the property * * @param property the property to be stored in the BanyanBD * @param strategy dedicates how to apply the property */ public ApplyResponse apply(Property property, Strategy strategy) throws BanyanDBException { PropertyStore store = new PropertyStore(checkNotNull(this.channel)); return store.apply(property, strategy); } /** * Find property * * @param group group of the metadata * @param name name of the metadata * @param id identity of the property * @param tags tags to be returned * @return property if it can be found */ public Property findProperty(String group, String name, String id, String... tags) throws BanyanDBException { PropertyStore store = new PropertyStore(checkNotNull(this.channel)); try { return store.get(group, name, id, tags); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * List Properties * * @param group group of the metadata * @param name name of the metadata * @return all properties belonging to the group and the name */ public List findProperties(String group, String name) throws BanyanDBException { return findProperties(group, name, null, null); } /** * List Properties * * @param group group of the metadata * @param name name of the metadata * @param ids identities of the properties * @param tags tags to be returned * @return all properties belonging to the group and the name */ public List findProperties(String group, String name, List ids, List tags) throws BanyanDBException { PropertyStore store = new PropertyStore(checkNotNull(this.channel)); return store.list(group, name, ids, tags); } /** * Delete property * * @param group group of the metadata * @param name name of the metadata * @param id identity of the property * @param tags tags to be deleted. If null, the property is deleted * @return if this property has been deleted */ public DeleteResponse deleteProperty(String group, String name, String id, String... tags) throws BanyanDBException { PropertyStore store = new PropertyStore(checkNotNull(this.channel)); return store.delete(group, name, id, tags); } /** * Keep alive the property * * @param leaseId lease id of the property */ public void keepAliveProperty(long leaseId) throws BanyanDBException { PropertyStore store = new PropertyStore(checkNotNull(this.channel)); store.keepAlive(leaseId); } /** * Try to find the group defined * * @param name name of the group * @return the group found in BanyanDB. Otherwise, null is returned. */ public Group findGroup(String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); try { return new GroupMetadataRegistry(checkNotNull(this.channel)).get(name, name); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * Try to find the groups defined * * @return the groups found in BanyanDB */ public List findGroups() throws BanyanDBException { return new GroupMetadataRegistry(checkNotNull(this.channel)).list(""); } /** * Try to find the TopNAggregation from the BanyanDB with given group and name. * * @param group group of the TopNAggregation * @param name name of the TopNAggregation * @return TopNAggregation if found. Otherwise, null is returned. */ public TopNAggregation findTopNAggregation(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); try { return new TopNAggregationMetadataRegistry(checkNotNull(this.channel)).get(group, name); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * Try to find the TopNAggregations from the BanyanDB with given group. * * @param group group of the TopNAggregations * @return TopNAggregations if found. */ public List findTopNAggregations(String group) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); return new TopNAggregationMetadataRegistry(checkNotNull(this.channel)).list(group); } /** * Try to find the stream from the BanyanDB with given group and name. * * @param group group of the stream * @param name name of the stream * @return Steam if found. Otherwise, null is returned. */ public Stream findStream(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); try { return new StreamMetadataRegistry(checkNotNull(this.channel)).get(group, name); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * Try to find the streams from the BanyanDB with given group. * * @param group group of the streams * @return Streams if found. */ public List findStreams(String group) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); StreamMetadataRegistry registry = new StreamMetadataRegistry(checkNotNull(this.channel)); return registry.list(group); } /** * Try to find the measure from the BanyanDB with given group and name. * * @param group group of the measure * @param name name of the measure * @return Measure with index rules if found. Otherwise, null is returned. */ public Measure findMeasure(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); try { return new MeasureMetadataRegistry(checkNotNull(this.channel)).get(group, name); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return null; } throw ex; } } /** * Try to find the measures from the BanyanDB with given group. * * @param group group of the measures * @return Measures if found. */ public List findMeasures(String group) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); MeasureMetadataRegistry registry = new MeasureMetadataRegistry(checkNotNull(this.channel)); return registry.list(group); } private List findIndexRulesByGroupAndBindingName(String group, String bindingName) throws BanyanDBException { IndexRuleBindingMetadataRegistry irbRegistry = new IndexRuleBindingMetadataRegistry(checkNotNull(this.channel)); IndexRuleBinding irb; try { irb = irbRegistry.get(group, bindingName); } catch (BanyanDBException ex) { if (ex.getStatus().equals(Status.Code.NOT_FOUND)) { return Collections.emptyList(); } throw ex; } if (irb == null) { return Collections.emptyList(); } List indexRules = new ArrayList<>(irb.getRulesList().size()); return indexRules; } /** * Check if the given stream exists. * * @param group group of the stream * @param name name of the stream * @return ResourceExist which indicates whether group and stream exist */ public ResourceExist existStream(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return new StreamMetadataRegistry(checkNotNull(this.channel)).exist(group, name); } /** * Check if the given measure exists. * * @param group group of the measure * @param name name of the measure * @return ResourceExist which indicates whether group and measure exist */ public ResourceExist existMeasure(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return new MeasureMetadataRegistry(checkNotNull(this.channel)).exist(group, name); } /** * Check if the given TopNAggregation exists. * * @param group group of the TopNAggregation * @param name name of the TopNAggregation * @return ResourceExist which indicates whether group and TopNAggregation exist */ public ResourceExist existTopNAggregation(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return new TopNAggregationMetadataRegistry(checkNotNull(this.channel)).exist(group, name); } /** * Update the stream metadata cache from the server * @param group the group of the stream * @param name the name of the stream * @return the updated stream metadata, or null if the stream does not exist */ public MetadataCache.EntityMetadata updateStreamMetadataCacheFromSever(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return this.metadataCache.updateStreamFromSever(group, name); } /** * Update the measure metadata cache from the server * @param group the group of the measure * @param name the name of the measure * @return the updated measure metadata, or null if the measure does not exist */ public MetadataCache.EntityMetadata updateMeasureMetadataCacheFromSever(String group, String name) throws BanyanDBException { Preconditions.checkArgument(!Strings.isNullOrEmpty(group)); Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); return this.metadataCache.updateMeasureFromSever(group, name); } @Override public void close() throws IOException { connectionEstablishLock.lock(); if (!(this.channel instanceof ManagedChannel)) { return; } final ManagedChannel managedChannel = (ManagedChannel) this.channel; try { if (isConnected) { managedChannel.shutdown().awaitTermination(5, TimeUnit.SECONDS); isConnected = false; } } catch (InterruptedException interruptedException) { Thread.currentThread().interrupt(); log.warn("fail to wait for channel termination, shutdown now!", interruptedException); managedChannel.shutdownNow(); isConnected = false; } finally { connectionEstablishLock.unlock(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy