Skip to content

Commit 718f0ab

Browse files
committed
OMID-310 Make Zookeeper SASL login context name configurable
1 parent 12b7735 commit 718f0ab

12 files changed

Lines changed: 168 additions & 14 deletions

File tree

common/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@
4848
<artifactId>curator-framework</artifactId>
4949
</dependency>
5050

51+
<dependency>
52+
<groupId>org.apache.zookeeper</groupId>
53+
<artifactId>zookeeper</artifactId>
54+
<version>${zookeeper.version}</version>
55+
<scope>provided</scope>
56+
</dependency>
57+
5158
<dependency>
5259
<groupId>com.google.protobuf</groupId>
5360
<artifactId>protobuf-java</artifactId>

common/src/main/java/org/apache/omid/zk/ZKUtils.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.curator.framework.CuratorFramework;
2222
import org.apache.curator.framework.CuratorFrameworkFactory;
2323
import org.apache.curator.retry.ExponentialBackoffRetry;
24+
import org.apache.zookeeper.client.ZKClientConfig;
2425
import org.slf4j.Logger;
2526
import org.slf4j.LoggerFactory;
2627

@@ -31,16 +32,25 @@ public class ZKUtils {
3132

3233
private static final Logger LOG = LoggerFactory.getLogger(ZKUtils.class);
3334

34-
public static CuratorFramework initZKClient(String zkCluster, String namespace, int zkConnectionTimeoutInSec)
35+
public static CuratorFramework initZKClient(String zkCluster, String namespace, int zkConnectionTimeoutInSec, String zkLoginContextName)
3536
throws IOException {
3637

3738
LOG.info("Creating Zookeeper Client connecting to {}", zkCluster);
3839

40+
ZKClientConfig zkConfig = new ZKClientConfig();
41+
if (zkLoginContextName != null) {
42+
// TODO should we check if this exists ?
43+
// Or just error out with an unsuccessful connection, as we do now ?
44+
LOG.info("Using Login Context {} for Zookeeper", zkCluster);
45+
zkConfig.setProperty(ZKClientConfig.LOGIN_CONTEXT_NAME_KEY, zkLoginContextName);
46+
}
47+
3948
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
4049
CuratorFramework zkClient = CuratorFrameworkFactory.builder()
4150
.namespace(namespace)
4251
.connectString(zkCluster)
4352
.retryPolicy(retryPolicy)
53+
.zkClientConfig(zkConfig)
4454
.build();
4555

4656
zkClient.start();

hbase-client/src/main/java/org/apache/omid/transaction/HBaseTransactionManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.util.concurrent.ExecutionException;
2424
import java.util.concurrent.Executors;
2525

26+
import javax.security.auth.login.Configuration;
27+
2628
import org.apache.hadoop.hbase.client.Connection;
2729
import org.apache.hadoop.hbase.client.ConnectionFactory;
2830
import org.apache.hadoop.hbase.client.Get;
@@ -32,6 +34,7 @@
3234
import org.apache.omid.committable.hbase.HBaseCommitTable;
3335
import org.apache.omid.committable.hbase.HBaseCommitTableConfig;
3436
import org.apache.omid.tools.hbase.HBaseLogin;
37+
import org.apache.omid.tools.hbase.OmidKerberosTicketCacheConfiguration;
3538
import org.apache.omid.tso.client.CellId;
3639
import org.apache.omid.tso.client.OmidClientConfiguration.ConflictDetectionLevel;
3740
import org.apache.omid.tso.client.TSOClient;
@@ -73,6 +76,11 @@ public static TransactionManager newInstance(HBaseOmidClientConfiguration config
7376
throws IOException, InterruptedException {
7477
//Logging in to Secure HBase if required
7578
HBaseLogin.loginIfNeeded(configuration);
79+
//Installing Jaas Configuration if magic app name is configured
80+
if (OmidKerberosTicketCacheConfiguration.APP_NAME.equals(configuration.getOmidClientConfiguration().getZkLoginContextName())) {
81+
LOG.info("Installing OmidKerberosTicketCacheConfiguration");
82+
Configuration.setConfiguration(new OmidKerberosTicketCacheConfiguration());
83+
}
7684
return builder(configuration).build();
7785
}
7886

hbase-client/src/test/java/org/apache/omid/transaction/TestHALeaseManagementModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class TestHALeaseManagementModule extends AbstractModule {
5454

5555
@Override
5656
protected void configure() {
57-
install(new ZKModule(zkCluster, zkNamespace));
57+
install(new ZKModule(zkCluster, zkNamespace, null));
5858
}
5959

6060
@Provides
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.omid.tools.hbase;
19+
20+
import java.io.IOException;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import javax.security.auth.login.AppConfigurationEntry;
25+
import javax.security.auth.login.Configuration;
26+
27+
import org.apache.hadoop.hbase.security.User;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
/**
32+
* Programmatic Jaas configuration object, which adds a new app configuration called
33+
* _omid_kerberos_ticket_cache, and falls back to the Configuration in effect when this was called.
34+
* To be used for connecting to Zookeeper, to reuse the kerberos ticket cache set by Hadoop/HBase
35+
* Based on Hadoop's JaasConfiguration
36+
*/
37+
public class OmidKerberosTicketCacheConfiguration extends Configuration {
38+
39+
private static final Logger LOG =
40+
LoggerFactory.getLogger(OmidKerberosTicketCacheConfiguration.class);
41+
42+
private final javax.security.auth.login.Configuration baseConfig =
43+
javax.security.auth.login.Configuration.getConfiguration();
44+
45+
private final AppConfigurationEntry[] entry;
46+
47+
public static String APP_NAME = "_omid_kerberos_ticket_cache";
48+
49+
public OmidKerberosTicketCacheConfiguration() {
50+
super();
51+
Map<String, String> options = new HashMap<>();
52+
options.put("useTicketCache", "true");
53+
options.putAll(getPrincipalIfNeeded());
54+
entry =
55+
new AppConfigurationEntry[] { new AppConfigurationEntry(getKrb5LoginModuleName(),
56+
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) };
57+
}
58+
59+
@Override
60+
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
61+
return (APP_NAME.equals(name)) ? entry
62+
: ((baseConfig != null) ? baseConfig.getAppConfigurationEntry(name) : null);
63+
}
64+
65+
private String getKrb5LoginModuleName() {
66+
String krb5LoginModuleName;
67+
if (System.getProperty("java.vendor").contains("IBM")) {
68+
krb5LoginModuleName = "com.ibm.security.auth.module.Krb5LoginModule";
69+
} else {
70+
krb5LoginModuleName = "com.sun.security.auth.module.Krb5LoginModule";
71+
}
72+
return krb5LoginModuleName;
73+
}
74+
75+
private Map<String, String> getPrincipalIfNeeded() {
76+
HashMap<String, String> principalOptions = new HashMap<>();
77+
if (System.getProperty("java.vendor").contains("IBM")) {
78+
// The IBM Kerberos implementation does not pick up the cache entry without the
79+
// principal
80+
String principalName;
81+
try {
82+
principalName = User.getCurrent().getName();
83+
if (principalName == null || principalName.isEmpty()) {
84+
LOG.warn("Got empty principal name on IMB JVM");
85+
} else {
86+
principalOptions.put("principal", principalName);
87+
}
88+
} catch (IOException e) {
89+
LOG.warn("Could not determine principal on IBM JVM.", e);
90+
}
91+
92+
}
93+
return principalOptions;
94+
}
95+
96+
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
<guava.version>32.1.3-jre</guava.version>
169169
<!-- 2.12+ shades guava -->
170170
<curator.version>5.6.0</curator.version>
171+
<zookeeper.version>3.8.4</zookeeper.version>
171172
<snakeyaml.version>2.2</snakeyaml.version>
172173
<beanutils.version>1.9.4</beanutils.version>
173174
<commons-io.version>2.18.0</commons-io.version>

timestamp-storage/src/main/java/org/apache/omid/timestamp/storage/DefaultZKTimestampStorageModule.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ public class DefaultZKTimestampStorageModule extends AbstractModule {
2727

2828
private String zkCluster = "localhost:2181";
2929
private String namespace = "omid";
30+
private String zkLoginContextName;
3031

3132
@Override
3233
public void configure() {
33-
install(new ZKModule(zkCluster, namespace));
34+
install(new ZKModule(zkCluster, namespace, zkLoginContextName));
3435
install(new ZKTimestampStorageModule());
3536
}
3637

@@ -54,4 +55,12 @@ public void setNamespace(String namespace) {
5455
this.namespace = namespace;
5556
}
5657

58+
public String getZkLoginContextName() {
59+
return zkLoginContextName;
60+
}
61+
62+
public void setZkLoginContextName(String zkLoginContextName) {
63+
this.zkLoginContextName = zkLoginContextName;
64+
}
65+
5766
}

timestamp-storage/src/main/java/org/apache/omid/timestamp/storage/ZKModule.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,19 @@
2525
import javax.inject.Singleton;
2626
import java.io.IOException;
2727

28-
//TODO:IK: move to common?
28+
// TODO:IK: move to common?
29+
// The problem is that common doesn't depend on Guice, and we want to keep that that way.
30+
// Ideally, this would be in a new module, something like omid-server-common
2931
public class ZKModule extends AbstractModule {
3032

3133
private final String zkCluster;
3234
private final String namespace;
35+
private final String zkLoginContextName;
3336

34-
public ZKModule(String zkCluster, String namespace) {
37+
public ZKModule(String zkCluster, String namespace, String zkLoginContextName) {
3538
this.zkCluster = zkCluster;
3639
this.namespace = namespace;
40+
this.zkLoginContextName = zkLoginContextName;
3741
}
3842

3943
@Override
@@ -43,7 +47,7 @@ public void configure() {
4347
@Provides
4448
@Singleton
4549
CuratorFramework provideInitializedZookeeperClient() throws IOException {
46-
return ZKUtils.initZKClient(zkCluster, namespace, 10);
50+
return ZKUtils.initZKClient(zkCluster, namespace, 10, zkLoginContextName);
4751
}
4852

4953
// ----------------------------------------------------------------------------------------------------------------

transaction-client/src/main/java/org/apache/omid/tso/client/OmidClientConfiguration.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public enum ConflictDetectionLevel {CELL, ROW}
4545
private String zkCurrentTsoPath;
4646
private String zkNamespace;
4747
private int zkConnectionTimeoutInSecs;
48+
private String zkLoginContextName;
4849

4950
// Communication protocol related params
5051

@@ -202,6 +203,16 @@ public void setZkNamespace(String zkNamespace) {
202203
this.zkNamespace = zkNamespace;
203204
}
204205

206+
public String getZkLoginContextName() {
207+
return zkLoginContextName;
208+
}
209+
210+
@Inject(optional = true)
211+
@Named("omid.ha.zkLoginContextName")
212+
public void setZkLoginContextName(String zkLoginContextName) {
213+
this.zkLoginContextName = zkLoginContextName;
214+
}
215+
205216
public PostCommitMode getPostCommitMode() {
206217
return postCommitMode;
207218
}
@@ -353,6 +364,4 @@ public void setTsConfigProtocols(String tlsConfigProtocols) {
353364
this.tlsConfigProtocols = tlsConfigProtocols;
354365
}
355366

356-
357-
358367
}

transaction-client/src/main/java/org/apache/omid/tso/client/TSOClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ private TSOClient(OmidClientConfiguration omidConf) throws IOException {
135135
case HA:
136136
zkClient = ZKUtils.initZKClient(omidConf.getConnectionString(),
137137
omidConf.getZkNamespace(),
138-
omidConf.getZkConnectionTimeoutInSecs());
138+
omidConf.getZkConnectionTimeoutInSecs(),
139+
omidConf.getZkLoginContextName());
139140
zkCurrentTsoPath = omidConf.getZkCurrentTsoPath();
140141
configureCurrentTSOServerZNodeCache(zkCurrentTsoPath);
141142
String tsoInfo = getCurrentTSOInfoFoundInZK(zkCurrentTsoPath);

0 commit comments

Comments
 (0)