Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
34e7f58a
Commit
34e7f58a
authored
Jan 08, 2015
by
Harish Butani
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
introduce ThriftTypesGen tool
parent
402e3680
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
323 additions
and
0 deletions
+323
-0
ThriftParser.scala
...rg/apache/hadoop/metadata/tools/thrift/ThriftParser.scala
+16
-0
ThriftTypesGen.scala
.../apache/hadoop/metadata/tools/thrift/ThriftTypesGen.scala
+307
-0
No files found.
typesystem/src/main/scala/org/apache/hadoop/metadata/tools/thrift/ThriftParser.scala
View file @
34e7f58a
...
...
@@ -18,6 +18,9 @@
package
org.apache.hadoop.metadata.tools.thrift
import
org.apache.hadoop.metadata.MetadataException
import
org.apache.hadoop.metadata.types.DataTypes
import
scala.util.parsing.combinator.
{
ImplicitConversions
,
PackratParsers
}
import
scala.util.parsing.combinator.lexical.StdLexical
import
scala.util.parsing.combinator.syntactical.StandardTokenParsers
...
...
@@ -34,6 +37,19 @@ object BASE_TYPES extends Enumeration {
val
I32
=
Value
(
"i32"
)
val
I64
=
Value
(
"i64"
)
val
DOUBLE
=
Value
(
"double"
)
@throws
[
MetadataException
]
def
toPrimitiveTypeName
(
t
:
BASE_TYPES.Value
)
:
String
=
t
match
{
case
STRING
=>
DataTypes
.
STRING_TYPE
.
getName
case
SLIST
=>
DataTypes
.
STRING_TYPE
.
getName
case
BOOLEAN
=>
DataTypes
.
BOOLEAN_TYPE
.
getName
case
BYTE
=>
DataTypes
.
BYTE_TYPE
.
getName
case
I16
=>
DataTypes
.
SHORT_TYPE
.
getName
case
I32
=>
DataTypes
.
INT_TYPE
.
getName
case
I64
=>
DataTypes
.
LONG_TYPE
.
getName
case
DOUBLE
=>
DataTypes
.
DOUBLE_TYPE
.
getName
case
_
=>
throw
new
MetadataException
(
s
"Thrift BaseType ($t) not supported"
)
}
}
object
THRIFT_LANG
extends
Enumeration
{
...
...
typesystem/src/main/scala/org/apache/hadoop/metadata/tools/thrift/ThriftTypesGen.scala
0 → 100644
View file @
34e7f58a
/**
* 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.hadoop.metadata.tools.thrift
import
com.google.common.collect.ImmutableList
import
org.apache.hadoop.metadata.
{
TypesDef
,
MetadataException
}
import
org.apache.hadoop.metadata.types._
import
org.slf4j.
{
LoggerFactory
,
Logger
}
import
scala.io.Source
import
scala.util.
{
Success
,
Try
,
Failure
}
case
class
CompositeRelation
(
typeName
:
String
,
fieldName
:
String
,
reverseFieldName
:
Option
[
String
])
/**
* Convert a [[org.apache.hadoop.metadata.tools.thrift.ThriftDef ThriftDef]] to
* [[org.apache.hadoop.metadata.TypesDef TypesDef]]. Currently there are several restrictions:
*
* - CppIncludes, SEnums are not allowed
* - The only include allowed is that of "share/fb303/if/fb303.thrift". This include is ignored.
* Any other include will trigger an exception
* - Namespaces, TypeDefs, Contants, Unions, Exceptions, and Service definitions are ignored.
* - So for fields typeDefs are not applied.
* - Field Constant values are ignored.
* - Type Annotations, XSD information is ignored.
*
* Thrift Structs can be mapped to Structs, Traits for Classes. The caller can specify their preference by
* providing the structNames, classNames and thriftNames parameters. A Struct that is not in one of these 3
* lists is not mapped.
*
* The ThriftDef doesn't specify if a relationship is composite. For e.g. in the thrift definition
* {{{
* struct Person {
1: string name,
2: Address addr,
}
struct Address {
1: string street,
2: string city,
}
* }}}
*
* If Person and Address are mapped to classes, you may not to make the Person -> Address a Composite relation.
* The caller can specify these in the 'compositeRelations' parameter.
*
*/
class
ThriftTypesGen
(
val
structNames
:
List
[
String
],
val
classNames
:
List
[
String
],
val
traitNames
:
List
[
String
],
val
compositeRelations
:
List
[
CompositeRelation
])
{
/**
* for a (typeName, fieldName) specifies (isComposite, reverseName)
* if entry doesn't exist than field is not composite.
*/
private
var
compositeRelsMap
:
Map
[(
String
,
String
)
,
(
Boolean
,
Option
[
String
])]
=
Map
()
private
val
LOG
:
Logger
=
LoggerFactory
.
getLogger
(
classOf
[
ThriftTypesGen
])
def
apply
(
thriftResource
:
String
)
:
TypesDef
=
{
val
tDef
=
parseThrift
(
thriftResource
)
tDef
.
flatMap
(
buildCompositeRelations
).
flatMap
(
typesDef
)
match
{
case
Success
(
t
)
=>
t
case
Failure
(
v
)
=>
throw
v
}
}
private
def
parseThrift
(
thriftResource
:
String
)
:
Try
[
ThriftDef
]
=
{
Try
{
LOG
.
debug
(
"Parsing Thrift resource {}"
,
thriftResource
)
val
is
=
getClass
().
getResourceAsStream
(
thriftResource
)
val
src
:
Source
=
Source
.
fromInputStream
(
is
)
val
thriftStr
:
String
=
src
.
getLines
().
mkString
(
"\n"
)
val
p
=
new
ThriftParser
var
thriftDef
:
Option
[
ThriftDef
]
=
p
(
thriftStr
)
thriftDef
match
{
case
Some
(
s
)
=>
s
case
None
=>
{
LOG
.
debug
(
"Parse for thrift resource {} failed"
,
thriftResource
)
throw
new
MetadataException
(
s
"Failed to parse thrift resource: $thriftResource"
)
}
}
}
}
@throws
[
MetadataException
]
private
def
dataTypeName
(
fT
:
FieldType
)
:
String
=
fT
match
{
case
IdentifierType
(
n
)
=>
n
case
BaseType
(
typ
,
_
)
=>
BASE_TYPES
.
toPrimitiveTypeName
(
typ
)
case
ListType
(
elemType
,
_
,
_
)
=>
DataTypes
.
arrayTypeName
(
dataTypeName
(
elemType
))
case
SetType
(
elemType
,
_
,
_
)
=>
DataTypes
.
arrayTypeName
(
dataTypeName
(
elemType
))
case
MapType
(
keyType
,
valueType
,
_
,
_
)
=>
DataTypes
.
mapTypeName
(
dataTypeName
(
keyType
),
dataTypeName
(
valueType
))
}
private
def
enumValue
(
e
:
EnumValueDef
,
defId
:
Int
)
:
EnumValue
=
e
match
{
case
EnumValueDef
(
value
,
Some
(
id
),
_
)
=>
new
EnumValue
(
value
,
id
.
value
)
case
EnumValueDef
(
value
,
None
,
_
)
=>
new
EnumValue
(
value
,
defId
)
}
private
def
enumDef
(
td
:
TypesDef
,
e
:
EnumDef
)
:
Try
[
TypesDef
]
=
{
Success
(
td
.
copy
(
enumTypes
=
td
.
enumTypes
:+
new
EnumTypeDefinition
(
e
.
name
,
e
.
enumValues
.
zipWithIndex
.
map
(
t
=>
enumValue
(
t
.
_1
,
-
t
.
_2
))
:_
*
))
)
}
private
val
FB_INCLUDE
=
"share/fb303/if/fb303.thrift"
private
def
includeDef
(
td
:
TypesDef
,
i
:
IncludeDef
)
:
Try
[
TypesDef
]
=
{
Try
{
if
(
i
.
value
!=
FB_INCLUDE
)
{
throw
new
MetadataException
(
s
"Unsupported Include ${i.value}, only fb303.thrift is currently allowed."
)
}
td
}
}
private
def
cppIncludeDef
(
td
:
TypesDef
,
i
:
CppIncludeDef
)
:
Try
[
TypesDef
]
=
{
Try
{
throw
new
MetadataException
(
s
"Unsupported CppInclude ${i.value}."
)
}
}
private
def
namespaceDef
(
td
:
TypesDef
,
i
:
NamespaceDef
)
:
Try
[
TypesDef
]
=
{
Try
{
LOG
.
debug
(
s
"Ignoring Namespace definition $i"
)
td
}
}
private
def
constantDef
(
td
:
TypesDef
,
i
:
ConstDef
)
:
Try
[
TypesDef
]
=
{
Try
{
LOG
.
debug
(
s
"Ignoring ConstantDef definition $i"
)
td
}
}
private
def
senumDef
(
td
:
TypesDef
,
i
:
SEnumDef
)
:
Try
[
TypesDef
]
=
{
Try
{
throw
new
MetadataException
(
s
"Unsupported SEnums ${i}."
)
}
}
private
def
fieldDef
(
typName
:
String
,
fd
:
FieldDef
)
:
AttributeDefinition
=
{
val
name
:
String
=
fd
.
name
val
dTName
:
String
=
dataTypeName
(
fd
.
fieldType
)
var
m
:
Multiplicity
=
Multiplicity
.
OPTIONAL
if
(
fd
.
requiredNess
)
{
m
=
Multiplicity
.
REQUIRED
}
fd
.
fieldType
match
{
case
_
:
ListType
=>
m
=
Multiplicity
.
COLLECTION
case
_
:
SetType
=>
m
=
Multiplicity
.
SET
case
_
=>
()
}
var
isComposite
=
false
var
reverseAttrName
:
String
=
null
val
r
=
compositeRelsMap
.
get
((
typName
,
name
))
if
(
r
.
isDefined
)
{
isComposite
=
r
.
get
.
_1
if
(
r
.
get
.
_2
.
isDefined
)
{
reverseAttrName
=
r
.
get
.
_2
.
get
}
}
new
AttributeDefinition
(
name
,
dTName
,
m
,
isComposite
,
reverseAttrName
)
}
private
def
structDef
(
td
:
TypesDef
,
structDef
:
StructDef
)
:
Try
[
TypesDef
]
=
Try
{
val
typeName
:
String
=
structDef
.
name
typeName
match
{
case
t
if
structNames
contains
t
=>
td
.
copy
(
structTypes
=
td
.
structTypes
:+
new
StructTypeDefinition
(
typeName
,
structDef
.
fields
.
map
(
fieldDef
(
typeName
,
_
)).
toArray
))
case
t
:
String
if
traitNames
contains
t
=>
{
val
ts
=
td
.
traitTypes
:+
new
HierarchicalTypeDefinition
[
TraitType
](
classOf
[
TraitType
],
typeName
,
ImmutableList
.
of
[
String
](),
structDef
.
fields
.
map
(
fieldDef
(
typeName
,
_
)).
toArray
)
td
.
copy
(
traitTypes
=
ts
)
}
case
t
:
String
if
classNames
contains
t
=>
{
val
cs
=
td
.
classTypes
:+
new
HierarchicalTypeDefinition
[
ClassType
](
classOf
[
ClassType
],
typeName
,
ImmutableList
.
of
[
String
](),
structDef
.
fields
.
map
(
fieldDef
(
typeName
,
_
)).
toArray
)
td
.
copy
(
classTypes
=
cs
)
}
case
_
=>
td
}
}
private
def
unionDef
(
td
:
TypesDef
,
i
:
UnionDef
)
:
Try
[
TypesDef
]
=
{
Try
{
LOG
.
debug
(
s
"Ignoring Union definition $i"
)
td
}
}
private
def
exceptionDef
(
td
:
TypesDef
,
i
:
ExceptionDef
)
:
Try
[
TypesDef
]
=
{
Try
{
LOG
.
debug
(
s
"Ignoring Exception definition $i"
)
td
}
}
private
def
serviceDef
(
td
:
TypesDef
,
i
:
ServiceDef
)
:
Try
[
TypesDef
]
=
{
Try
{
LOG
.
debug
(
s
"Ignoring Service definition $i"
)
td
}
}
private
def
applyList
[
T
](
fn
:
(
TypesDef
,
T
)
=>
Try
[
TypesDef
])(
td
:
TypesDef
,
l
:
List
[
T
])
:
Try
[
TypesDef
]
=
{
l
.
foldLeft
[
Try
[
TypesDef
]](
Success
(
td
))((
b
,
a
)
=>
b
.
flatMap
({
Unit
=>
fn
(
td
,
a
)}))
}
private
def
includes
=
applyList
(
includeDef
)
_
private
def
cppIncludes
=
applyList
(
cppIncludeDef
)
_
private
def
namespaces
=
applyList
(
namespaceDef
)
_
private
def
constants
=
applyList
(
constantDef
)
_
private
def
enums
=
applyList
(
enumDef
)
_
private
def
senums
=
applyList
(
senumDef
)
_
private
def
structs
=
applyList
(
structDef
)
_
private
def
unions
=
applyList
(
unionDef
)
_
private
def
exceptions
=
applyList
(
exceptionDef
)
_
private
def
services
=
applyList
(
serviceDef
)
_
def
buildCompositeRelations
(
thriftDef
:
ThriftDef
)
:
Try
[
ThriftDef
]
=
Try
{
compositeRelations
.
foreach
{
cr
=>
val
sDef
=
thriftDef
.
structs
.
find
(
_
.
name
==
cr
.
typeName
)
if
(
!
sDef
.
isDefined
)
{
throw
new
MetadataException
(
s
"Unknown Struct (${cr.typeName}) specified in CompositeRelation"
)
}
val
fDef
=
sDef
.
get
.
fields
.
find
(
_
.
name
==
cr
.
fieldName
)
if
(
!
fDef
.
isDefined
)
{
throw
new
MetadataException
(
s
"Unknown Field (${cr.fieldName}) specified in CompositeRelation"
)
}
compositeRelsMap
=
compositeRelsMap
+
((
cr
.
typeName
,
cr
.
fieldName
)
->
(
true
,
cr
.
reverseFieldName
))
if
(
cr
.
reverseFieldName
.
isDefined
)
{
val
reverseStructName
=
dataTypeName
(
fDef
.
get
.
fieldType
)
val
reverseStructDef
=
thriftDef
.
structs
.
find
(
_
.
name
==
reverseStructName
)
if
(
!
reverseStructDef
.
isDefined
)
{
throw
new
MetadataException
(
s
"Cannot find Struct $reverseStructName in CompositeRelation $cr"
)
}
val
rfDef
=
reverseStructDef
.
get
.
fields
.
find
(
_
.
name
==
cr
.
reverseFieldName
)
if
(
!
rfDef
.
isDefined
)
{
throw
new
MetadataException
(
s
"Unknown Reverse Field (${cr.reverseFieldName}) specified in CompositeRelation"
)
}
List
(
cr
,
CompositeRelation
(
reverseStructName
,
cr
.
reverseFieldName
.
get
,
Some
(
cr
.
fieldName
)))
compositeRelsMap
=
compositeRelsMap
+
((
reverseStructName
,
cr
.
reverseFieldName
.
get
)
->
(
false
,
Some
(
cr
.
fieldName
)))
}
}
thriftDef
}
def
typesDef
(
thriftDef
:
ThriftDef
)
:
Try
[
TypesDef
]
=
{
var
tDef
:
Try
[
TypesDef
]
=
Try
{
TypesDef
(
Seq
(),
Seq
(),
Seq
(),
Seq
())}
tDef
.
flatMap
((
t
:
TypesDef
)
=>
includes
(
t
,
thriftDef
.
includes
)).
flatMap
((
t
:
TypesDef
)
=>
cppIncludes
(
t
,
thriftDef
.
cppIncludes
))
tDef
=
tDef
.
flatMap
((
t
:
TypesDef
)
=>
includes
(
t
,
thriftDef
.
includes
)).
flatMap
((
t
:
TypesDef
)
=>
cppIncludes
(
t
,
thriftDef
.
cppIncludes
)).
flatMap
((
t
:
TypesDef
)
=>
namespaces
(
t
,
thriftDef
.
namespaces
)).
flatMap
((
t
:
TypesDef
)
=>
constants
(
t
,
thriftDef
.
constants
)).
flatMap
((
t
:
TypesDef
)
=>
senums
(
t
,
thriftDef
.
senums
)).
flatMap
((
t
:
TypesDef
)
=>
enums
(
t
,
thriftDef
.
enums
)).
flatMap
((
t
:
TypesDef
)
=>
structs
(
t
,
thriftDef
.
structs
)).
flatMap
((
t
:
TypesDef
)
=>
unions
(
t
,
thriftDef
.
unions
)).
flatMap
((
t
:
TypesDef
)
=>
exceptions
(
t
,
thriftDef
.
xceptions
)).
flatMap
((
t
:
TypesDef
)
=>
services
(
t
,
thriftDef
.
services
))
tDef
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment