blob: 85a935c5cfa95d3d833eca97d46a7168b75f4623 [file] [log] [blame]
/*
* 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.ignite.internal.processors.hadoop.impl.delegate;
import java.io.IOException;
import java.security.PrivilegedExceptionAction;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.ignite.IgniteException;
import org.apache.ignite.hadoop.fs.KerberosHadoopFileSystemFactory;
import org.apache.ignite.hadoop.fs.v1.IgniteHadoopFileSystem;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.A;
/**
* Kerberos Hadoop file system factory delegate.
*/
public class HadoopKerberosFileSystemFactoryDelegate extends HadoopBasicFileSystemFactoryDelegate {
/** The re-login interval. */
private long reloginInterval;
/** Time of last re-login attempt, in system milliseconds. */
private volatile long lastReloginTime;
/** Login user. */
private UserGroupInformation user;
/**
* Constructor.
*
* @param proxy Proxy.
*/
public HadoopKerberosFileSystemFactoryDelegate(KerberosHadoopFileSystemFactory proxy) {
super(proxy);
}
/** {@inheritDoc} */
@Override public FileSystem getWithMappedName(String name) throws IOException {
reloginIfNeeded();
return super.getWithMappedName(name);
}
/** {@inheritDoc} */
@Override protected FileSystem create(String usrName) throws IOException, InterruptedException {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUser(usrName, user);
return proxyUgi.doAs(new PrivilegedExceptionAction<FileSystem>() {
@Override public FileSystem run() throws Exception {
FileSystem fs = FileSystem.get(fullUri, cfg);
if (workDir != null)
fs.setWorkingDirectory(workDir);
return fs;
}
});
}
@Override public void start() throws IgniteException {
super.start();
KerberosHadoopFileSystemFactory proxy0 = (KerberosHadoopFileSystemFactory)proxy;
A.ensure(!F.isEmpty(proxy0.getKeyTab()), "keyTab cannot not be empty.");
A.ensure(!F.isEmpty(proxy0.getKeyTabPrincipal()), "keyTabPrincipal cannot not be empty.");
A.ensure(proxy0.getReloginInterval() >= 0, "reloginInterval cannot not be negative.");
reloginInterval = proxy0.getReloginInterval();
try {
UserGroupInformation.setConfiguration(cfg);
user = UserGroupInformation.loginUserFromKeytabAndReturnUGI(proxy0.getKeyTabPrincipal(),
proxy0.getKeyTab());
}
catch (IOException ioe) {
throw new IgniteException("Failed login from keytab [keyTab=" + proxy0.getKeyTab() +
", keyTabPrincipal=" + proxy0.getKeyTabPrincipal() + ']', ioe);
}
}
/**
* Re-logins the user if needed.
* First, the re-login interval defined in factory is checked. The re-login attempts will be not more
* frequent than one attempt per {@code reloginInterval}.
* Second, {@code UserGroupInformation.checkTGTAndReloginFromKeytab()} method invoked that gets existing
* TGT and checks its validity. If the TGT is expired or is close to expiry, it performs re-login.
*
* <p>This operation expected to be called upon each operation with the file system created with the factory.
* As long as {@link #get(String)} operation is invoked upon each file {@link IgniteHadoopFileSystem}, there
* is no need to invoke it otherwise specially.
*
* @throws IOException If login fails.
*/
private void reloginIfNeeded() throws IOException {
long now = System.currentTimeMillis();
if (now >= lastReloginTime + reloginInterval) {
user.checkTGTAndReloginFromKeytab();
lastReloginTime = now;
}
}
}