| package org.apache.cassandra.stress.settings; |
| /* |
| * |
| * 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. |
| * |
| */ |
| |
| |
| import java.io.Serializable; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Map; |
| |
| import com.datastax.driver.core.AuthProvider; |
| import com.datastax.driver.core.PlainTextAuthProvider; |
| import com.datastax.driver.core.ProtocolOptions; |
| import com.datastax.driver.core.ProtocolVersion; |
| |
| public class SettingsMode implements Serializable |
| { |
| |
| public final ConnectionAPI api; |
| public final ConnectionStyle style; |
| public final CqlVersion cqlVersion; |
| public final ProtocolVersion protocolVersion; |
| |
| public final String username; |
| public final String password; |
| public final String authProviderClassname; |
| public final AuthProvider authProvider; |
| |
| public final Integer maxPendingPerConnection; |
| public final Integer connectionsPerHost; |
| |
| private final String compression; |
| |
| public SettingsMode(GroupedOptions options) |
| { |
| if (options instanceof Cql3Options) |
| { |
| cqlVersion = CqlVersion.CQL3; |
| Cql3Options opts = (Cql3Options) options; |
| protocolVersion = "NEWEST_SUPPORTED".equals(opts.protocolVersion.value()) |
| ? ProtocolVersion.NEWEST_SUPPORTED |
| : ProtocolVersion.fromInt(Integer.parseInt(opts.protocolVersion.value())); |
| api = opts.mode().displayPrefix.equals("native") ? ConnectionAPI.JAVA_DRIVER_NATIVE : ConnectionAPI.THRIFT; |
| style = opts.useUnPrepared.setByUser() ? ConnectionStyle.CQL : ConnectionStyle.CQL_PREPARED; |
| compression = ProtocolOptions.Compression.valueOf(opts.useCompression.value().toUpperCase()).name(); |
| username = opts.user.value(); |
| password = opts.password.value(); |
| maxPendingPerConnection = opts.maxPendingPerConnection.value().isEmpty() ? null : Integer.valueOf(opts.maxPendingPerConnection.value()); |
| connectionsPerHost = opts.connectionsPerHost.value().isEmpty() ? null : Integer.valueOf(opts.connectionsPerHost.value()); |
| authProviderClassname = opts.authProvider.value(); |
| if (authProviderClassname != null) |
| { |
| try |
| { |
| Class<?> clazz = Class.forName(authProviderClassname); |
| if (!AuthProvider.class.isAssignableFrom(clazz)) |
| throw new IllegalArgumentException(clazz + " is not a valid auth provider"); |
| // check we can instantiate it |
| if (PlainTextAuthProvider.class.equals(clazz)) |
| { |
| authProvider = (AuthProvider) clazz.getConstructor(String.class, String.class) |
| .newInstance(username, password); |
| } else |
| { |
| authProvider = (AuthProvider) clazz.newInstance(); |
| } |
| } |
| catch (Exception e) |
| { |
| throw new IllegalArgumentException("Invalid auth provider class: " + opts.authProvider.value(), e); |
| } |
| } |
| else |
| { |
| authProvider = null; |
| } |
| } |
| else if (options instanceof Cql3SimpleNativeOptions) |
| { |
| cqlVersion = CqlVersion.CQL3; |
| Cql3SimpleNativeOptions opts = (Cql3SimpleNativeOptions) options; |
| protocolVersion = ProtocolVersion.NEWEST_SUPPORTED; |
| api = ConnectionAPI.SIMPLE_NATIVE; |
| style = opts.usePrepared.setByUser() ? ConnectionStyle.CQL_PREPARED : ConnectionStyle.CQL; |
| compression = ProtocolOptions.Compression.NONE.name(); |
| username = null; |
| password = null; |
| authProvider = null; |
| authProviderClassname = null; |
| maxPendingPerConnection = null; |
| connectionsPerHost = null; |
| } |
| else if (options instanceof ThriftOptions) |
| { |
| ThriftOptions opts = (ThriftOptions) options; |
| protocolVersion = ProtocolVersion.NEWEST_SUPPORTED; |
| cqlVersion = CqlVersion.NOCQL; |
| api = opts.smart.setByUser() ? ConnectionAPI.THRIFT_SMART : ConnectionAPI.THRIFT; |
| style = ConnectionStyle.THRIFT; |
| compression = ProtocolOptions.Compression.NONE.name(); |
| username = opts.user.value(); |
| password = opts.password.value(); |
| authProviderClassname = null; |
| authProvider = null; |
| maxPendingPerConnection = null; |
| connectionsPerHost = null; |
| } |
| else |
| throw new IllegalStateException(); |
| } |
| |
| public ProtocolOptions.Compression compression() |
| { |
| return ProtocolOptions.Compression.valueOf(compression); |
| } |
| |
| // Option Declarations |
| |
| private static final class Cql3NativeOptions extends Cql3Options |
| { |
| final OptionSimple mode = new OptionSimple("native", "", null, "", true); |
| OptionSimple mode() |
| { |
| return mode; |
| } |
| } |
| |
| private static final class Cql3ThriftOptions extends Cql3Options |
| { |
| final OptionSimple mode = new OptionSimple("thrift", "", null, "", true); |
| OptionSimple mode() |
| { |
| return mode; |
| } |
| } |
| |
| private static abstract class Cql3Options extends GroupedOptions |
| { |
| final OptionSimple api = new OptionSimple("cql3", "", null, "", true); |
| final OptionSimple protocolVersion = new OptionSimple("protocolVersion=", "[2-4]+", "NEWEST_SUPPORTED", "CQL Protocol Version", false); |
| final OptionSimple useUnPrepared = new OptionSimple("unprepared", "", null, "force use of unprepared statements", false); |
| final OptionSimple useCompression = new OptionSimple("compression=", "none|lz4|snappy", "none", "", false); |
| final OptionSimple port = new OptionSimple("port=", "[0-9]+", "9046", "", false); |
| final OptionSimple user = new OptionSimple("user=", ".+", null, "username", false); |
| final OptionSimple password = new OptionSimple("password=", ".+", null, "password", false); |
| final OptionSimple authProvider = new OptionSimple("auth-provider=", ".*", null, "Fully qualified implementation of com.datastax.driver.core.AuthProvider", false); |
| final OptionSimple maxPendingPerConnection = new OptionSimple("maxPending=", "[0-9]+", "", "Maximum pending requests per connection", false); |
| final OptionSimple connectionsPerHost = new OptionSimple("connectionsPerHost=", "[0-9]+", "", "Number of connections per host", false); |
| |
| abstract OptionSimple mode(); |
| @Override |
| public List<? extends Option> options() |
| { |
| return Arrays.asList(mode(), useUnPrepared, api, useCompression, port, user, password, authProvider, |
| maxPendingPerConnection, connectionsPerHost, protocolVersion); |
| } |
| } |
| |
| |
| private static final class Cql3SimpleNativeOptions extends GroupedOptions |
| { |
| final OptionSimple api = new OptionSimple("cql3", "", null, "", true); |
| final OptionSimple useSimpleNative = new OptionSimple("simplenative", "", null, "", true); |
| final OptionSimple usePrepared = new OptionSimple("prepared", "", null, "", false); |
| final OptionSimple port = new OptionSimple("port=", "[0-9]+", "9046", "", false); |
| |
| @Override |
| public List<? extends Option> options() |
| { |
| return Arrays.asList(useSimpleNative, usePrepared, api, port); |
| } |
| } |
| |
| private static final class ThriftOptions extends GroupedOptions |
| { |
| final OptionSimple api = new OptionSimple("thrift", "", null, "", true); |
| final OptionSimple smart = new OptionSimple("smart", "", null, "", false); |
| final OptionSimple user = new OptionSimple("user=", ".+", null, "username", false); |
| final OptionSimple password = new OptionSimple("password=", ".+", null, "password", false); |
| |
| |
| @Override |
| public List<? extends Option> options() |
| { |
| return Arrays.asList(api, smart, user, password); |
| } |
| } |
| |
| // CLI Utility Methods |
| |
| public static SettingsMode get(Map<String, String[]> clArgs) |
| { |
| String[] params = clArgs.remove("-mode"); |
| if (params == null) |
| { |
| Cql3NativeOptions opts = new Cql3NativeOptions(); |
| opts.accept("cql3"); |
| opts.accept("native"); |
| opts.accept("prepared"); |
| return new SettingsMode(opts); |
| } |
| |
| GroupedOptions options = GroupedOptions.select(params, new ThriftOptions(), new Cql3NativeOptions(), new Cql3SimpleNativeOptions()); |
| if (options == null) |
| { |
| printHelp(); |
| System.out.println("Invalid -mode options provided, see output for valid options"); |
| System.exit(1); |
| } |
| return new SettingsMode(options); |
| } |
| |
| public static void printHelp() |
| { |
| GroupedOptions.printOptions(System.out, "-mode", new ThriftOptions(), new Cql3NativeOptions(), new Cql3SimpleNativeOptions()); |
| } |
| |
| public static Runnable helpPrinter() |
| { |
| return new Runnable() |
| { |
| @Override |
| public void run() |
| { |
| printHelp(); |
| } |
| }; |
| } |
| } |