1919package org .apache .hadoop .hive .metastore .client .builder ;
2020
2121import org .apache .commons .lang3 .exception .ExceptionUtils ;
22+ import org .apache .commons .lang3 .reflect .ConstructorUtils ;
23+ import org .apache .commons .lang3 .tuple .Pair ;
2224import org .apache .hadoop .conf .Configuration ;
2325import org .apache .hadoop .hive .metastore .HiveMetaHookLoader ;
2426import org .apache .hadoop .hive .metastore .IMetaStoreClient ;
3234import org .slf4j .Logger ;
3335import org .slf4j .LoggerFactory ;
3436
37+ import java .lang .reflect .Constructor ;
3538import java .util .Map ;
3639import java .util .Objects ;
40+ import java .util .concurrent .ConcurrentHashMap ;
3741import java .util .function .Function ;
3842
3943public class HiveMetaStoreClientBuilder {
4044 private static final Logger LOG = LoggerFactory .getLogger (HiveMetaStoreClientBuilder .class );
45+ private static final Map <Class <? extends IMetaStoreClient >, MetaStoreClientFactory >
46+ CLIENT_FACTORIES = new ConcurrentHashMap <>();
4147
4248 private final Configuration conf ;
4349 private IMetaStoreClient client ;
4450
45- public HiveMetaStoreClientBuilder (Configuration conf ) {
46- this . conf = Objects . requireNonNull ( conf );
51+ public HiveMetaStoreClientBuilder (Configuration configuration ) throws MetaException {
52+ this ( configuration , true );
4753 }
4854
49- public HiveMetaStoreClientBuilder newClient (boolean allowEmbedded ) throws MetaException {
50- this .client = createClient (conf , allowEmbedded );
51- return this ;
55+ public HiveMetaStoreClientBuilder (Configuration configuration , boolean allowEmbedded ) throws MetaException {
56+ this .conf = Objects .requireNonNull (configuration );
57+ Class <? extends IMetaStoreClient > mscClass = MetastoreConf .getClass (
58+ conf , MetastoreConf .ConfVars .METASTORE_CLIENT_IMPL ,
59+ ThriftHiveMetaStoreClient .class , IMetaStoreClient .class );
60+ this .client = createClient (conf , mscClass , allowEmbedded );
5261 }
5362
54- public HiveMetaStoreClientBuilder client (IMetaStoreClient client ) {
55- this .client = client ;
56- return this ;
63+ public HiveMetaStoreClientBuilder (Configuration configuration , String clientImpl ,
64+ boolean allowEmbedded ) throws MetaException {
65+ this .conf = Objects .requireNonNull (configuration );
66+ Class <? extends IMetaStoreClient > baseClass =
67+ JavaUtils .getClass (clientImpl , IMetaStoreClient .class );
68+ this .client = createClient (configuration , baseClass , allowEmbedded );
69+ }
70+
71+ public HiveMetaStoreClientBuilder (Configuration configuration , IMetaStoreClient client ) {
72+ this .conf = Objects .requireNonNull (configuration );
73+ this .client = Objects .requireNonNull (client );
5774 }
5875
5976 public HiveMetaStoreClientBuilder enhanceWith (Function <IMetaStoreClient , IMetaStoreClient > wrapperFunction ) {
@@ -80,17 +97,15 @@ public IMetaStoreClient build() {
8097 return Objects .requireNonNull (client );
8198 }
8299
83- private static IMetaStoreClient createClient (Configuration conf , boolean allowEmbedded ) throws MetaException {
84- Class <? extends IMetaStoreClient > mscClass = MetastoreConf .getClass (
85- conf , MetastoreConf .ConfVars .METASTORE_CLIENT_IMPL ,
86- ThriftHiveMetaStoreClient .class , IMetaStoreClient .class );
87- LOG .info ("Using {} as a base MetaStoreClient" , mscClass .getName ());
88-
89- IMetaStoreClient baseMetaStoreClient = null ;
100+ private static IMetaStoreClient createClient (Configuration conf ,
101+ Class <? extends IMetaStoreClient > mscClass , boolean allowEmbedded ) throws MetaException {
90102 try {
91- baseMetaStoreClient = JavaUtils .newInstance (mscClass ,
92- new Class []{Configuration .class , boolean .class },
93- new Object []{conf , allowEmbedded });
103+ LOG .info ("Using {} as a base MetaStoreClient" , mscClass .getName ());
104+ MetaStoreClientFactory factory = CLIENT_FACTORIES .get (mscClass );
105+ if (factory == null ) {
106+ CLIENT_FACTORIES .put (mscClass , factory = new MetaStoreClientFactory (mscClass ));
107+ }
108+ return factory .createClient (conf , allowEmbedded );
94109 } catch (Throwable t ) {
95110 // Reflection by JavaUtils will throw RuntimeException, try to get real MetaException here.
96111 Throwable rootCause = ExceptionUtils .getRootCause (t );
@@ -100,7 +115,34 @@ private static IMetaStoreClient createClient(Configuration conf, boolean allowEm
100115 throw new MetaException (rootCause .getMessage ());
101116 }
102117 }
118+ }
103119
104- return baseMetaStoreClient ;
120+ private static class MetaStoreClientFactory {
121+ private Constructor <? extends IMetaStoreClient > bestMatchingCtr ;
122+ private Function <Pair <Configuration , Boolean >, Object []> argsTransformer ;
123+
124+ MetaStoreClientFactory (Class <? extends IMetaStoreClient > mscClass ) {
125+ Constructor <? extends IMetaStoreClient > candidate =
126+ ConstructorUtils .getMatchingAccessibleConstructor (mscClass , Configuration .class , boolean .class );
127+ if (candidate != null ) {
128+ this .bestMatchingCtr = candidate ;
129+ this .argsTransformer = args -> new Object [] {args .getLeft (), (boolean ) args .getRight ()};
130+ } else if ((candidate = ConstructorUtils .getMatchingAccessibleConstructor (mscClass , Configuration .class ,
131+ HiveMetaHookLoader .class , Boolean .class )) != null ) {
132+ this .bestMatchingCtr = candidate ;
133+ this .argsTransformer = args ->
134+ new Object [] {args .getLeft (), null , Boolean .valueOf (args .getRight ())};
135+ } else if ((candidate = ConstructorUtils .getMatchingAccessibleConstructor (mscClass , Configuration .class )) != null ) {
136+ this .bestMatchingCtr = candidate ;
137+ this .argsTransformer = args -> new Object [] {args .getLeft ()};
138+ }
139+ if (bestMatchingCtr == null ) {
140+ throw new RuntimeException ("No matching constructor found for this IMetaStoreClient " + mscClass );
141+ }
142+ }
143+
144+ IMetaStoreClient createClient (Configuration conf , boolean allowEmbedded ) throws Exception {
145+ return bestMatchingCtr .newInstance (argsTransformer .apply (Pair .of (conf , allowEmbedded )));
146+ }
105147 }
106148}
0 commit comments