Skip to content

Commit

Permalink
HIVE_CLI_SERVICE_PROTOCOL_V11 (#235)
Browse files Browse the repository at this point in the history
* HIVE_CLI_SERVICE_PROTOCOL_V11

* pom

* style

* tests

* travis

* code cover
  • Loading branch information
yaooqinn committed May 26, 2020
1 parent b9a50d6 commit 651db99
Show file tree
Hide file tree
Showing 158 changed files with 69,105 additions and 318 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- stage: spark2.4
language: scala
script:
- ./build/mvn clean install -Dmaven.javadoc.skip=true -B -V
- mvn clean install -Dmaven.javadoc.skip=true -B -V

after_success:
- bash <(curl -s https://codecov.io/bash)
4 changes: 2 additions & 2 deletions kyuubi-assembly/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
</dependency>

<dependency>
<groupId>yaooqinn</groupId>
<artifactId>kyuubi-thrift</artifactId>
<groupId>org.apache.kyuubi</groupId>
<artifactId>kyuubi-hive-thrift</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* (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
* 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,
Expand All @@ -15,7 +15,7 @@
* limitations under the License.
*/

package yaooqinn.kyuubi
package org.apache.kyuubi

import org.slf4j.LoggerFactory

Expand All @@ -35,18 +35,26 @@ trait Logging {
}

def warn(message: => Any): Unit = {
logger.warn(message.toString)
if (logger.isWarnEnabled) {
logger.warn(message.toString)
}
}

def warn(message: => Any, t: Throwable): Unit = {
logger.warn(message.toString, t)
if (logger.isWarnEnabled) {
logger.warn(message.toString, t)
}
}

def error(message: => Any, t: Throwable): Unit = {
logger.error(message.toString, t)
if (logger.isErrorEnabled) {
logger.error(message.toString, t)
}
}

def error(message: => Any): Unit = {
logger.error(message.toString)
if (logger.isErrorEnabled) {
logger.error(message.toString)
}
}
}
12 changes: 7 additions & 5 deletions kyuubi-common/src/main/scala/org/apache/kyuubi/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ import java.util.Properties

import scala.collection.JavaConverters._

import yaooqinn.kyuubi.Logging

private[kyuubi] object Utils extends Logging {

import KyuubiConf._
import org.apache.kyuubi.config.KyuubiConf._

def strToSeq(s: String): Seq[String] = {
require(s != null)
s.split(",").map(_.trim).filter(_.nonEmpty)
}

def getSystemProperties: Map[String, String] = {
System.getProperties.asScala.toMap
sys.props.toMap
}

def getDefaultPropertiesFile(env: Map[String, String] = sys.env): Option[File] = {
Expand Down Expand Up @@ -58,5 +61,4 @@ private[kyuubi] object Utils extends Logging {
}
}.getOrElse(Map.empty)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* 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.kyuubi.config

private[kyuubi] case class ConfigBuilder(key: String) {

private[config] var _doc = ""
private[config] var _version = ""

def doc(s: String): ConfigBuilder = {
_doc = s
this
}

def version(s: String): ConfigBuilder = {
_version = s
this
}

private def toNumber[T](s: String, converter: String => T, configType: String): T = {
try {
converter(s.trim)
} catch {
case _: NumberFormatException =>
throw new IllegalArgumentException(s"$key should be $configType, but was $s")
}
}

def intConf: TypedConfigBuilder[Int] = {
new TypedConfigBuilder(this, toNumber(_, _.toInt, "int"))
}

def longConf: TypedConfigBuilder[Long] = {
new TypedConfigBuilder(this, toNumber(_, _.toLong, "long"))
}

def doubleConf: TypedConfigBuilder[Double] = {
new TypedConfigBuilder(this, toNumber(_, _.toDouble, "double"))
}

def booleanConf: TypedConfigBuilder[Boolean] = {
def toBoolean(s: String) = try {
s.trim.toBoolean
} catch {
case e: IllegalArgumentException =>
throw new IllegalArgumentException(s"$key should be boolean, but was $s", e)
}
new TypedConfigBuilder(this, toBoolean)
}

def stringConf: TypedConfigBuilder[String] = {
new TypedConfigBuilder(this, identity)
}
}

private[kyuubi] case class TypedConfigBuilder[T](
parent: ConfigBuilder,
fromStr: String => T,
toStr: T => String) {

import ConfigHelpers._

def this(parent: ConfigBuilder, fromStr: String => T) =
this(parent, fromStr, Option[T](_).map(_.toString).orNull)

def transform(fn: T => T): TypedConfigBuilder[T] = this.copy(fromStr = s => fn(fromStr(s)))

/** Checks if the user-provided value for the config matches the validator. */
def checkValue(validator: T => Boolean, errMsg: String): TypedConfigBuilder[T] = {
transform { v =>
if (!validator(v)) throw new IllegalArgumentException(errMsg)
v
}
}

/** Check that user-provided values for the config match a pre-defined set. */
def checkValues(validValues: Set[T]): TypedConfigBuilder[T] = {
transform { v =>
if (!validValues.contains(v)) {
throw new IllegalArgumentException(
s"The value of ${parent.key} should be one of ${validValues.mkString(", ")}, but was $v")
}
v
}
}

/** Turns the config entry into a sequence of values of the underlying type. */
def toSequence: TypedConfigBuilder[Seq[T]] = {
TypedConfigBuilder(parent, strToSeq(_, fromStr), seqToStr(_, toStr))
}

def createOptional: OptionalConfigEntry[T] = OptionalConfigEntry(
parent.key, fromStr, toStr, parent._doc, parent._version)

def createWithDefault(default: T): ConfigEntry[T] = default match {
case d: String => createWithDefaultString(d)
case _ =>
val d = fromStr(toStr(default))
ConfigEntryWithDefault(parent.key, d, fromStr, toStr, parent._doc, parent._version)
}

def createWithDefaultString(default: String): ConfigEntryWithDefaultString[T] = {
ConfigEntryWithDefaultString(parent.key, default, fromStr, toStr, parent._doc, parent._version)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* 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.kyuubi.config

trait ConfigEntry[T] {
def key: String
def valueConverter: String => T
def strConverter: T => String
def doc: String
def version: String

def defaultValStr: String
def defaultVal: Option[T] = None

final override def toString: String = {
s"ConfigEntry(key=$key, defaultValue=$defaultValStr, doc=$doc, version=$version)"
}

final protected def readString(provider: ConfigProvider): Option[String] = {
provider.get(key)
}

def readFrom(conf: ConfigProvider): T

ConfigEntry.registerEntry(this)
}

case class OptionalConfigEntry[T](
key: String,
rawValueConverter: String => T,
rawStrConverter: T => String,
doc: String,
version: String) extends ConfigEntry[Option[T]] {
override def valueConverter: String => Option[T] = s => Option(rawValueConverter(s))

override def strConverter: Option[T] => String = v => v.map(rawStrConverter).orNull

override def defaultValStr: String = ConfigEntry.UNDEFINED

override def readFrom(conf: ConfigProvider): Option[T] = {
readString(conf).map(rawValueConverter)
}
}

case class ConfigEntryWithDefault[T](
key: String,
_defaultVal: T,
valueConverter: String => T,
strConverter: T => String,
doc: String,
version: String) extends ConfigEntry[T] {
override def defaultValStr: String = strConverter(_defaultVal)

override def defaultVal: Option[T] = Option(_defaultVal)

override def readFrom(conf: ConfigProvider): T = {
readString(conf).map(valueConverter).getOrElse(_defaultVal)
}
}

case class ConfigEntryWithDefaultString[T](
key: String,
_defaultVal: String,
valueConverter: String => T,
strConverter: T => String,
doc: String,
version: String) extends ConfigEntry[T] {
override def defaultValStr: String = _defaultVal

override def defaultVal: Option[T] = Some(valueConverter(_defaultVal))

override def readFrom(conf: ConfigProvider): T = {
val value = readString(conf).getOrElse(_defaultVal)
valueConverter(value)
}
}

object ConfigEntry {
val UNDEFINED = "<undefined>"

private val knownConfigs = new java.util.concurrent.ConcurrentHashMap[String, ConfigEntry[_]]()

def registerEntry(entry: ConfigEntry[_]): Unit = {
val existing = knownConfigs.putIfAbsent(entry.key, entry)
require(existing == null, s"Config entry ${entry.key} already registered!")
}

def findEntry(key: String): ConfigEntry[_] = knownConfigs.get(key)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.kyuubi.config

import org.apache.kyuubi.Utils

object ConfigHelpers {

def strToSeq[T](str: String, converter: String => T): Seq[T] = {
Utils.strToSeq(str).map(converter)
}

def seqToStr[T](v: Seq[T], stringConverter: T => String): String = {
v.map(stringConverter).mkString(",")
}

def toNumber[T](s: String, converter: String => T, key: String, configType: String): T = {
try {
converter(s.trim)
} catch {
case _: NumberFormatException =>
throw new IllegalArgumentException(s"$key should be $configType, but was $s")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.kyuubi.config

private[kyuubi] class ConfigProvider(conf: java.util.Map[String, String]) {

def get(key: String): Option[String] = {
if (key.startsWith(KYUUBI_PREFIX)) {
Option(conf.get(key))
} else {
None
}
}

}

0 comments on commit 651db99

Please sign in to comment.