Java tutorial
/* * 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.bookkeeper.stream.protocol.util; import static com.google.common.base.Preconditions.checkArgument; import com.google.common.base.Strings; import com.google.common.collect.Lists; import java.util.List; import org.apache.bookkeeper.common.util.Revisioned; import org.apache.bookkeeper.stream.proto.NamespaceConfiguration; import org.apache.bookkeeper.stream.proto.RangeProperties; import org.apache.bookkeeper.stream.proto.StreamConfiguration; import org.apache.bookkeeper.stream.proto.StreamMetadata.LifecycleState; import org.apache.bookkeeper.stream.proto.StreamMetadata.ServingState; import org.apache.bookkeeper.stream.proto.StreamName; import org.apache.bookkeeper.stream.proto.StreamProperties; import org.apache.bookkeeper.stream.proto.storage.CreateNamespaceRequest; import org.apache.bookkeeper.stream.proto.storage.CreateStreamRequest; import org.apache.bookkeeper.stream.proto.storage.DeleteNamespaceRequest; import org.apache.bookkeeper.stream.proto.storage.DeleteStreamRequest; import org.apache.bookkeeper.stream.proto.storage.GetActiveRangesRequest; import org.apache.bookkeeper.stream.proto.storage.GetNamespaceRequest; import org.apache.bookkeeper.stream.proto.storage.GetStorageContainerEndpointRequest; import org.apache.bookkeeper.stream.proto.storage.GetStorageContainerEndpointResponse; import org.apache.bookkeeper.stream.proto.storage.GetStreamRequest; import org.apache.bookkeeper.stream.proto.storage.OneStorageContainerEndpointRequest; import org.apache.bookkeeper.stream.proto.storage.OneStorageContainerEndpointResponse; import org.apache.bookkeeper.stream.proto.storage.StatusCode; import org.apache.bookkeeper.stream.proto.storage.StorageContainerEndpoint; import org.apache.commons.lang3.tuple.Pair; /** * Protocol related utils. */ public class ProtoUtils { /** * Check if two key ranges overlaps with each other. * * @param meta1 first key range * @param meta2 second key range * @return true if two key ranges overlaps */ public static boolean keyRangeOverlaps(RangeProperties meta1, RangeProperties meta2) { return keyRangeOverlaps(meta1.getStartHashKey(), meta1.getEndHashKey(), meta2.getStartHashKey(), meta2.getEndHashKey()); } public static boolean keyRangeOverlaps(Pair<Long, Long> range1, Pair<Long, Long> range2) { return keyRangeOverlaps(range1.getLeft(), range1.getRight(), range2.getLeft(), range2.getRight()); } public static boolean keyRangeOverlaps(RangeProperties range1, Pair<Long, Long> range2) { return keyRangeOverlaps(range1.getStartHashKey(), range1.getEndHashKey(), range2.getLeft(), range2.getRight()); } public static boolean keyRangeOverlaps(Pair<Long, Long> range1, RangeProperties range2) { return keyRangeOverlaps(range1.getLeft(), range1.getRight(), range2.getStartHashKey(), range2.getEndHashKey()); } static boolean keyRangeOverlaps(long startKey1, long endKey1, long startKey2, long endKey2) { return endKey2 > startKey1 && startKey2 < endKey1; } /** * Validate namespace name. * * @return true if it is a valid namespace name. otherwise false. */ public static boolean validateNamespaceName(String name) { return validateStreamName(name); } /** * Validate stream name. * * <p>follow the rules that dlog uses for validating stream name. * * @return true if it is a valid namespace name. otherwise false. */ public static boolean validateStreamName(String name) { if (Strings.isNullOrEmpty(name)) { return false; } for (int i = 0; i < name.length(); i++) { char c = name.charAt(i); if (c == 0 || c == ' ' || c == '<' || c == '>' || c > '\u0000' && c < '\u001f' || c > '\u007f' && c < '\u009f' || c > '\ud800' && c < '\uf8ff' || c > '\ufff0' && c < '\uffff') { return false; } } return true; } public static List<RangeProperties> split(long streamId, int numInitialRanges, long nextRangeId, StorageContainerPlacementPolicy placementPolicy) { int numRanges = Math.max(2, numInitialRanges); if (numRanges % 2 != 0) { // round up to odd number numRanges = numRanges + 1; } long rangeSize = Long.MAX_VALUE / (numRanges / 2); long startKey = Long.MIN_VALUE; List<RangeProperties> ranges = Lists.newArrayListWithExpectedSize(numRanges); for (int idx = 0; idx < numRanges; ++idx) { long endKey = startKey + rangeSize; if (numRanges - 1 == idx) { endKey = Long.MAX_VALUE; } long rangeId = nextRangeId++; RangeProperties props = RangeProperties.newBuilder().setStartHashKey(startKey).setEndHashKey(endKey) .setStorageContainerId(placementPolicy.placeStreamRange(streamId, rangeId)).setRangeId(rangeId) .build(); startKey = endKey; ranges.add(props); } return ranges; } /** * Check if the stream is created. * * @param state stream state * @return true if the stream is in created state. otherwise, false. */ public static boolean isStreamCreated(LifecycleState state) { checkArgument(state != LifecycleState.UNRECOGNIZED); return LifecycleState.UNINIT != state && LifecycleState.CREATING != state; } /** * Check if the stream is writable. * * @param state stream state * @return true if the stream is writable. otherwise, false. */ public static boolean isStreamWritable(ServingState state) { checkArgument(state != ServingState.UNRECOGNIZED); return ServingState.WRITABLE == state; } // // Location API // /** * Create a {@link GetStorageContainerEndpointRequest}. * * @param storageContainers list of storage containers * @return a get storage container endpoint request. */ public static GetStorageContainerEndpointRequest createGetStorageContainerEndpointRequest( List<Revisioned<Long>> storageContainers) { GetStorageContainerEndpointRequest.Builder builder = GetStorageContainerEndpointRequest.newBuilder(); for (Revisioned<Long> storageContainer : storageContainers) { builder.addRequests(OneStorageContainerEndpointRequest.newBuilder() .setStorageContainer(storageContainer.getValue()).setRevision(storageContainer.getRevision())); } return builder.build(); } /** * Create a {@link GetStorageContainerEndpointResponse}. * * @param endpoints list of storage container endpoints * @return a get storage container endpoint response. */ public static GetStorageContainerEndpointResponse createGetStorageContainerEndpointResponse( List<StorageContainerEndpoint> endpoints) { GetStorageContainerEndpointResponse.Builder builder = GetStorageContainerEndpointResponse.newBuilder(); builder.setStatusCode(StatusCode.SUCCESS); for (StorageContainerEndpoint endpoint : endpoints) { builder.addResponses(OneStorageContainerEndpointResponse.newBuilder().setStatusCode(StatusCode.SUCCESS) .setEndpoint(endpoint)); } return builder.build(); } // // Meta Range API // public static GetActiveRangesRequest createGetActiveRangesRequest(long streamId) { return GetActiveRangesRequest.newBuilder().setStreamId(streamId).build(); } public static GetActiveRangesRequest createGetActiveRangesRequest(StreamProperties streamProps) { return GetActiveRangesRequest.newBuilder().setStreamId(streamProps.getStreamId()) .setStreamProps(streamProps).build(); } // // Namespace API // /** * Create a {@link CreateNamespaceRequest}. * * @param nsName namespace name * @param nsConf namespace conf * @return a create namespace request. */ public static CreateNamespaceRequest createCreateNamespaceRequest(String nsName, NamespaceConfiguration nsConf) { return CreateNamespaceRequest.newBuilder().setName(nsName).setNsConf(nsConf).build(); } /** * Create a {@link DeleteNamespaceRequest}. * * @param colName namespace name * @return a delete namespace request. */ public static DeleteNamespaceRequest createDeleteNamespaceRequest(String colName) { return DeleteNamespaceRequest.newBuilder().setName(colName).build(); } /** * Create a {@link GetNamespaceRequest}. * * @param colName namespace name * @return a get namespace request. */ public static GetNamespaceRequest createGetNamespaceRequest(String colName) { return GetNamespaceRequest.newBuilder().setName(colName).build(); } // // Stream API // /** * Create a {@link CreateStreamRequest}. * * @param nsName namespace name * @param streamName stream name * @param streamConf stream configuration * @return a create stream request. */ public static CreateStreamRequest createCreateStreamRequest(String nsName, String streamName, StreamConfiguration streamConf) { return CreateStreamRequest.newBuilder().setNsName(nsName).setName(streamName).setStreamConf(streamConf) .build(); } /** * Create a {@link GetStreamRequest}. * * @param nsName namespace name * @param streamName stream name * @return a create stream request. */ public static GetStreamRequest createGetStreamRequest(String nsName, String streamName) { return GetStreamRequest.newBuilder() .setStreamName(StreamName.newBuilder().setNamespaceName(nsName).setStreamName(streamName)).build(); } /** * Create a {@link GetStreamRequest}. * * @param streamId stream id * @return a create stream request. */ public static GetStreamRequest createGetStreamRequest(long streamId) { return GetStreamRequest.newBuilder().setStreamId(streamId).build(); } /** * Create a {@link DeleteStreamRequest}. * * @param nsName namespace name * @param streamName stream name * @return a create stream request. */ public static DeleteStreamRequest createDeleteStreamRequest(String nsName, String streamName) { return DeleteStreamRequest.newBuilder().setName(streamName).setNsName(nsName).build(); } }