| /* |
| * 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.drill.exec.client; |
| |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.drill.common.Version; |
| import org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos; |
| import org.apache.drill.exec.proto.UserProtos.RpcType; |
| import org.apache.drill.exec.rpc.user.UserRpcUtils; |
| |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Maps; |
| import com.google.common.collect.Sets; |
| |
| /** |
| * A enumeration of server methods, and the version they were introduced |
| * |
| * it allows to introduce new methods without changing the protocol, with client |
| * being able to gracefully handle cases were method is not handled by the server. |
| */ |
| public enum ServerMethod { |
| /** |
| * Submitting a query |
| */ |
| RUN_QUERY(RpcType.RUN_QUERY, Constants.DRILL_0_0_0), |
| |
| /** |
| * Plan a query without executing it |
| */ |
| PLAN_QUERY(RpcType.QUERY_PLAN_FRAGMENTS, Constants.DRILL_0_0_0), |
| |
| /** |
| * Cancel an existing query |
| */ |
| CANCEL_QUERY(RpcType.CANCEL_QUERY, Constants.DRILL_0_0_0), |
| |
| /** |
| * Resume a query |
| */ |
| RESUME_PAUSED_QUERY(RpcType.RESUME_PAUSED_QUERY, Constants.DRILL_0_0_0), |
| |
| /** |
| * Prepare a query for deferred execution |
| */ |
| PREPARED_STATEMENT(RpcType.CREATE_PREPARED_STATEMENT, Constants.DRILL_1_8_0), |
| |
| /** |
| * Get catalog metadata |
| */ |
| GET_CATALOGS(RpcType.GET_CATALOGS, Constants.DRILL_1_8_0), |
| |
| /** |
| * Get schemas metadata |
| */ |
| GET_SCHEMAS(RpcType.GET_SCHEMAS, Constants.DRILL_1_8_0), |
| |
| /** |
| * Get tables metadata |
| */ |
| GET_TABLES(RpcType.GET_TABLES, Constants.DRILL_1_8_0), |
| |
| /** |
| * Get columns metadata |
| */ |
| GET_COLUMNS(RpcType.GET_COLUMNS, Constants.DRILL_1_8_0), |
| |
| /** |
| * Get server metadata |
| */ |
| GET_SERVER_META(RpcType.GET_SERVER_META, Constants.DRILL_1_10_0); |
| |
| private static class Constants { |
| private static final Version DRILL_0_0_0 = new Version("0.0.0", 0, 0, 0, 0, ""); |
| private static final Version DRILL_1_8_0 = new Version("1.8.0", 1, 8, 0, 0, ""); |
| private static final Version DRILL_1_10_0 = new Version("1.10.0", 1, 10, 0, 0, ""); |
| } |
| |
| private static final Map<RpcType, ServerMethod> REVERSE_MAPPING; |
| static { |
| ImmutableMap.Builder<RpcType, ServerMethod> builder = ImmutableMap.builder(); |
| for(ServerMethod method: values()) { |
| builder.put(method.rpcType, method); |
| } |
| REVERSE_MAPPING = Maps.immutableEnumMap(builder.build()); |
| } |
| |
| private final RpcType rpcType; |
| private final Version minVersion; |
| |
| private ServerMethod(RpcType rpcType, Version minVersion) { |
| this.rpcType = rpcType; |
| this.minVersion = minVersion; |
| } |
| |
| public Version getMinVersion() { |
| return minVersion; |
| } |
| |
| /** |
| * Returns the list of methods supported by the server based on its advertised information. |
| * |
| * @param serverInfos the server information |
| * @return a immutable set of capabilities |
| */ |
| static final Set<ServerMethod> getSupportedMethods(Iterable<RpcType> supportedMethods, RpcEndpointInfos serverInfos) { |
| ImmutableSet.Builder<ServerMethod> builder = ImmutableSet.builder(); |
| |
| for(RpcType supportedMethod: supportedMethods) { |
| ServerMethod method = REVERSE_MAPPING.get(supportedMethod); |
| if (method == null) { |
| // The server might have newer methods we don't know how to handle yet. |
| continue; |
| } |
| builder.add(method); |
| } |
| |
| // Fallback to version detection to cover the gap between Drill 1.8.0 and Drill 1.10.0 |
| if (serverInfos == null) { |
| return Sets.immutableEnumSet(builder.build()); |
| } |
| |
| Version serverVersion = UserRpcUtils.getVersion(serverInfos); |
| for(ServerMethod capability: ServerMethod.values()) { |
| if (serverVersion.compareTo(capability.getMinVersion()) >= 0) { |
| builder.add(capability); |
| } |
| } |
| |
| return Sets.immutableEnumSet(builder.build()); |
| } |
| } |