blob: fca613788f6551d234d167baf7f12d7824d38a7a [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.oozie.client;
import org.apache.commons.codec.CharEncoding;
import org.apache.falcon.security.CurrentUser;
import org.apache.falcon.security.SecurityUtil;
import org.apache.falcon.util.RuntimeProperties;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.oozie.client.rest.RestConstants;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* Wrapped Oozie Client that does proxy the requests.
*/
public class ProxyOozieClient extends AuthOozieClient {
private static final Logger LOG = LoggerFactory.getLogger(ProxyOozieClient.class);
private static final Map<String, String> NONE = new HashMap<String, String>();
public ProxyOozieClient(String oozieUrl) {
super(oozieUrl, SecurityUtil.getAuthenticationType());
if (org.apache.log4j.Logger.getLogger(getClass()).isDebugEnabled()) {
setDebugMode(1);
}
}
public Properties getConfiguration() throws OozieClientException {
return (new OozieConfiguration(RestConstants.ADMIN_CONFIG_RESOURCE)).call();
}
public Properties getProperties() throws OozieClientException {
return (new OozieConfiguration(RestConstants.ADMIN_JAVA_SYS_PROPS_RESOURCE)).call();
}
@Override
protected HttpURLConnection createConnection(URL url, final String method)
throws IOException, OozieClientException {
final URL decoratedUrl = decorateUrlWithUser(url);
LOG.debug("ProxyOozieClient.createConnection: u={}, m={}", url, method);
// Login User "falcon" has the kerberos credentials
UserGroupInformation loginUserUGI = UserGroupInformation.getLoginUser();
try {
return loginUserUGI.doAs(new PrivilegedExceptionAction<HttpURLConnection>() {
public HttpURLConnection run() throws Exception {
HttpURLConnection conn = ProxyOozieClient.super.createConnection(decoratedUrl, method);
int connectTimeout = Integer.parseInt(
RuntimeProperties.get().getProperty("oozie.connect.timeout", "1000"));
conn.setConnectTimeout(connectTimeout);
int readTimeout = Integer.parseInt(
RuntimeProperties.get().getProperty("oozie.read.timeout", "45000"));
conn.setReadTimeout(readTimeout);
return conn;
}
});
} catch (InterruptedException e) {
throw new IOException("Could not connect to oozie: " + e.getMessage(), e);
}
}
protected URL decorateUrlWithUser(URL url) throws IOException {
String strUrl = url.toString();
if (!strUrl.contains(OozieClient.USER_NAME)) {
// decorate the url with the proxy user in request
String paramSeparator = (strUrl.contains("?")) ? "&" : "?";
strUrl += paramSeparator + OozieClient.USER_NAME + "="
+ UserGroupInformation.getLoginUser().getUserName();
// strUrl += "&" + RestConstants.DO_AS_PARAM + "=" + CurrentUser.getUser();
url = new URL(strUrl);
LOG.debug("Decorated url with user info: {}", url);
}
return url;
}
private class OozieConfiguration extends ClientCallable<Properties> {
public OozieConfiguration(String resource) {
super("GET", RestConstants.ADMIN, resource, NONE);
}
@Override
protected Properties call(HttpURLConnection conn)
throws IOException, OozieClientException {
conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
Reader reader = new InputStreamReader(conn.getInputStream(), CharEncoding.UTF_8);
JSONObject json = (JSONObject) JSONValue.parse(reader);
Properties props = new Properties();
props.putAll(json);
return props;
} else {
handleError(conn);
return null;
}
}
}
@Override
public SYSTEM_MODE getSystemMode() throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<SYSTEM_MODE>() {
public SYSTEM_MODE call() throws Exception {
return ProxyOozieClient.super.getSystemMode();
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public String submit(final Properties conf) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<String>() {
public String call() throws Exception {
return ProxyOozieClient.super.submit(conf);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public String dryrun(final Properties conf) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<String>() {
public String call() throws Exception {
return ProxyOozieClient.super.dryrun(conf);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void start(final String jobId) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public String call() throws Exception {
ProxyOozieClient.super.start(jobId);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public String run(final Properties conf) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<String>() {
public String call() throws Exception {
return ProxyOozieClient.super.run(conf);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void reRun(final String jobId, final Properties conf) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.reRun(jobId, conf);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void suspend(final String jobId) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.suspend(jobId);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void resume(final String jobId) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.resume(jobId);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void kill(final String jobId) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.kill(jobId);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void change(final String jobId, final String changeValue) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.change(jobId, changeValue);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public WorkflowJob getJobInfo(final String jobId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<WorkflowJob>() {
public WorkflowJob call() throws Exception {
return ProxyOozieClient.super.getJobInfo(jobId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public WorkflowJob getJobInfo(final String jobId, final int start, final int len)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<WorkflowJob>() {
public WorkflowJob call() throws Exception {
return ProxyOozieClient.super.getJobInfo(jobId, start, len);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public WorkflowAction getWorkflowActionInfo(final String actionId)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<WorkflowAction>() {
public WorkflowAction call() throws Exception {
return ProxyOozieClient.super.getWorkflowActionInfo(actionId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public String getJobLog(final String jobId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<String>() {
public String call() throws Exception {
return ProxyOozieClient.super.getJobLog(jobId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void getJobLog(final String jobId, final String logRetrievalType,
final String logRetrievalScope, final PrintStream ps)
throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.getJobLog(jobId, logRetrievalType, logRetrievalScope, ps);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public String getJobDefinition(final String jobId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<String>() {
public String call() throws Exception {
return ProxyOozieClient.super.getJobDefinition(jobId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public BundleJob getBundleJobInfo(final String jobId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<BundleJob>() {
public BundleJob call() throws Exception {
return ProxyOozieClient.super.getBundleJobInfo(jobId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public CoordinatorJob getCoordJobInfo(final String jobId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<CoordinatorJob>() {
public CoordinatorJob call() throws Exception {
return ProxyOozieClient.super.getCoordJobInfo(jobId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public CoordinatorJob getCoordJobInfo(final String jobId, final String filter,
final int start, final int len)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<CoordinatorJob>() {
public CoordinatorJob call() throws Exception {
return ProxyOozieClient.super.getCoordJobInfo(jobId, filter, start, len);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public CoordinatorAction getCoordActionInfo(final String actionId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<CoordinatorAction>() {
public CoordinatorAction call() throws Exception {
return ProxyOozieClient.super.getCoordActionInfo(actionId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public List<CoordinatorAction> reRunCoord(final String jobId, final String rerunType,
final String scope, final boolean refresh,
final boolean noCleanup)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<List<CoordinatorAction>>() {
public List<CoordinatorAction> call() throws Exception {
return ProxyOozieClient.super.reRunCoord(jobId, rerunType, scope, refresh, noCleanup);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public List<CoordinatorAction> reRunCoord(final String jobId, final String rerunType, final String scope,
final boolean refresh, final boolean noCleanup,
final boolean failed, final Properties props)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<List<CoordinatorAction>>() {
public List<CoordinatorAction> call() throws Exception {
return ProxyOozieClient.super.reRunCoord(jobId, rerunType, scope, refresh, noCleanup, failed,
props);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public Void reRunBundle(final String jobId, final String coordScope, final String dateScope,
final boolean refresh, final boolean noCleanup)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<Void>() {
public Void call() throws Exception {
return ProxyOozieClient.super.reRunBundle(jobId, coordScope, dateScope, refresh, noCleanup);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public List<WorkflowJob> getJobsInfo(final String filter, final int start, final int len)
throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<List<WorkflowJob>>() {
public List<WorkflowJob> call() throws Exception {
return ProxyOozieClient.super.getJobsInfo(filter, start, len);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public List<WorkflowJob> getJobsInfo(final String filter) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<List<WorkflowJob>>() {
public List<WorkflowJob> call() throws Exception {
return ProxyOozieClient.super.getJobsInfo(filter);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public void getSlaInfo(final int start, final int len, final String filter) throws OozieClientException {
try {
doAs(CurrentUser.getUser(), new Callable<Object>() {
public Object call() throws Exception {
ProxyOozieClient.super.getSlaInfo(start, len, filter);
return null;
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public String getJobId(final String externalId) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<String>() {
public String call() throws Exception {
return ProxyOozieClient.super.getJobId(externalId);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public List<CoordinatorJob> getCoordJobsInfo(final String filter, final int start,
final int len) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<List<CoordinatorJob>>() {
public List<CoordinatorJob> call() throws Exception {
return ProxyOozieClient.super.getCoordJobsInfo(filter, start, len);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
@Override
public List<BundleJob> getBundleJobsInfo(final String filter, final int start,
final int len) throws OozieClientException {
try {
return doAs(CurrentUser.getUser(), new Callable<List<BundleJob>>() {
public List<BundleJob> call() throws Exception {
return ProxyOozieClient.super.getBundleJobsInfo(filter, start, len);
}
});
} catch (OozieClientException e) {
throw e;
} catch (Exception e) {
throw new OozieClientException(e.toString(), e);
}
}
}