257 lines
8.6 KiB
Swift
257 lines
8.6 KiB
Swift
// 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 Foundation
|
|
import Thrift
|
|
|
|
public enum Protocol: String {
|
|
case binary
|
|
case compact
|
|
case header
|
|
case json
|
|
}
|
|
|
|
public enum Transport: String {
|
|
case buffered
|
|
case framed
|
|
case http
|
|
case anonpipe
|
|
case zlib
|
|
}
|
|
|
|
public enum ServerType: String {
|
|
case simple
|
|
case threadPool = "thread-pool"
|
|
case threaded
|
|
case nonblocking
|
|
}
|
|
|
|
public enum ParserError: Error {
|
|
case unknownArgument(argument: String)
|
|
case missingParameter(argument: String)
|
|
case invalidParameter(argument: String, parameter: String)
|
|
|
|
case unsupportedOption
|
|
}
|
|
|
|
public class ParametersBase {
|
|
public var showHelp = false
|
|
public var port: Int?
|
|
public var domainSocket: String?
|
|
public var namedPipe: String?
|
|
public var proto: Protocol?
|
|
public var transport: Transport?
|
|
public var multiplex = false
|
|
public var abstractNamespace = false
|
|
public var ssl = false
|
|
public var zlib = false
|
|
|
|
public init (arguments: [String]) throws {
|
|
if arguments.count > 1 {
|
|
for argument in arguments[1...] {
|
|
let equalSignPos = argument.firstIndex(of: "=") ?? argument.endIndex
|
|
let name = String(argument[..<equalSignPos])
|
|
let value: String? = (equalSignPos < argument.endIndex) ? String(argument[argument.index(equalSignPos, offsetBy: 1)..<argument.endIndex]) : nil
|
|
|
|
try processArgument(name: name, value: value)
|
|
}
|
|
}
|
|
|
|
fillDefaults()
|
|
try checkSupported()
|
|
}
|
|
|
|
open func processArgument(name: String, value: String?) throws {
|
|
switch name {
|
|
case "-h", "--help":
|
|
showHelp = true
|
|
case "--port":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
port = Int(value!)
|
|
guard port != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
case "--domain-socket":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
domainSocket = value!
|
|
case "--named-pipe":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
namedPipe = value!
|
|
case "--transport":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
transport = Transport(rawValue: value!)
|
|
guard transport != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
case "--protocol":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
proto = Protocol(rawValue: value!)
|
|
guard proto != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
case "--multiplex":
|
|
multiplex = true
|
|
case "--abstract-namespace":
|
|
abstractNamespace = true
|
|
case "--ssl":
|
|
ssl = true
|
|
case "--zlib":
|
|
zlib = true
|
|
default:
|
|
throw ParserError.unknownArgument(argument: name)
|
|
}
|
|
}
|
|
|
|
open func fillDefaults() {
|
|
if port == nil && domainSocket == nil && namedPipe == nil {
|
|
port = 9090
|
|
}
|
|
|
|
if transport == nil {
|
|
transport = .buffered
|
|
}
|
|
|
|
if proto == nil {
|
|
proto = .binary
|
|
}
|
|
}
|
|
|
|
open func checkSupported() throws {
|
|
guard transport == .buffered || transport == .framed else { throw ParserError.unsupportedOption }
|
|
guard proto == .binary || proto == .compact else { throw ParserError.unsupportedOption }
|
|
}
|
|
}
|
|
|
|
public class TestClientParameters: ParametersBase {
|
|
public var host: String?
|
|
public var testLoops: Int?
|
|
public var threads: Int?
|
|
|
|
public func printHelp() {
|
|
print("""
|
|
Allowed options:
|
|
-h | --help produce help message
|
|
--host=arg (localhost) Host to connect
|
|
--port=arg (9090) Port number to connect
|
|
--domain-socket=arg Domain Socket (e.g. /tmp/ThriftTest.thrift),
|
|
instead of host and port
|
|
--named-pipe=arg Windows Named Pipe (e.g. MyThriftPipe)
|
|
--anon-pipes hRead hWrite Windows Anonymous Pipes pair (handles)
|
|
--abstract-namespace Create the domain socket in the Abstract Namespace
|
|
(no connection with filesystem pathnames)
|
|
--transport=arg (buffered) Transport: buffered, framed, http, evhttp, zlib
|
|
--protocol=arg (binary) Protocol: binary, compact, header, json
|
|
--multiplex Add TMultiplexedProtocol service name "ThriftTest"
|
|
--ssl Encrypted Transport using SSL
|
|
--zlib Wrap Transport with Zlib
|
|
-n=arg | --testloops=arg (1) Number of Tests
|
|
-t=arg | --threads=arg (1) Number of Test threads
|
|
""")
|
|
}
|
|
|
|
open override func processArgument(name: String, value: String?) throws {
|
|
switch name {
|
|
case "--host":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
host = value!
|
|
case "-n", "--testloops":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
testLoops = Int(value!)
|
|
guard testLoops != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
case "-t", "--threads":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
threads = Int(value!)
|
|
guard threads != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
default:
|
|
try super.processArgument(name: name, value: value)
|
|
}
|
|
}
|
|
|
|
open override func fillDefaults() {
|
|
super.fillDefaults()
|
|
|
|
if host == nil {
|
|
host = "localhost"
|
|
}
|
|
|
|
if testLoops == nil {
|
|
testLoops = 1
|
|
}
|
|
|
|
if threads == nil {
|
|
threads = 4
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TestServerParameters: ParametersBase {
|
|
public var serverType: ServerType?
|
|
public var processorEvents = false
|
|
public var workers: Int?
|
|
|
|
public func printHelp() {
|
|
print("""
|
|
Allowed options:
|
|
-h | --help produce help message
|
|
--port=arg (=9090) Port number to listen
|
|
--domain-socket=arg Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)
|
|
--named-pipe=arg Windows Named Pipe (e.g. MyThriftPipe)
|
|
--server-type=arg (=simple) type of server, "simple", "thread-pool",
|
|
"threaded", or "nonblocking"
|
|
--transport=arg (=buffered) transport: buffered, framed, http, anonpipe, zlib
|
|
--protocol=arg (=binary) protocol: binary, compact, header, json
|
|
--multiplex Add TMultiplexedProtocol service name "ThriftTest"
|
|
--abstract-namespace Create the domain socket in the Abstract Namespace
|
|
(no connection with filesystem pathnames)
|
|
--ssl Encrypted Transport using SSL
|
|
--zlib Wrapped Transport using Zlib
|
|
--processor-events processor-events
|
|
-n=arg | --workers=arg (=4) Number of thread pools workers. Only valid for
|
|
thread-pool server type
|
|
""")
|
|
}
|
|
|
|
open override func processArgument(name: String, value: String?) throws {
|
|
switch name {
|
|
case "--server-type":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
serverType = ServerType(rawValue: value!)
|
|
guard serverType != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
case "--processor-events":
|
|
processorEvents = true
|
|
case "-n", "--workers":
|
|
guard value != nil else { throw ParserError.missingParameter(argument: name) }
|
|
workers = Int(value!)
|
|
guard workers != nil else { throw ParserError.invalidParameter(argument: name, parameter: value!) }
|
|
default:
|
|
try super.processArgument(name: name, value: value)
|
|
}
|
|
}
|
|
|
|
open override func fillDefaults() {
|
|
super.fillDefaults()
|
|
|
|
if serverType == nil {
|
|
serverType = .simple
|
|
}
|
|
|
|
if workers == nil {
|
|
workers = 4
|
|
}
|
|
}
|
|
|
|
open override func checkSupported() throws {
|
|
try super.checkSupported()
|
|
guard serverType == .simple else { throw ParserError.unsupportedOption }
|
|
}
|
|
}
|
|
|