This project has retired. For details please refer to its Attic page.
Source code
001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019
020package org.apache.oozie.util;
021
022import java.io.BufferedReader;
023import java.io.IOException;
024import java.io.InputStream;
025import java.io.InputStreamReader;
026import java.net.HttpURLConnection;
027import java.net.URL;
028import java.security.PrivilegedExceptionAction;
029import java.util.Map;
030
031import org.apache.hadoop.security.UserGroupInformation;
032import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
033import org.apache.hadoop.security.authentication.client.AuthenticationException;
034import org.apache.hadoop.security.authentication.client.Authenticator;
035import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
036import org.apache.hadoop.security.authentication.client.PseudoAuthenticator;
037import org.apache.oozie.service.ConfigurationService;
038import org.apache.oozie.service.Services;
039
040public class AuthUrlClient {
041
042    public static final String SERVER_SERVER_AUTH_TYPE = "oozie.server.authentication.type";
043
044    private static XLog LOG = XLog.getLog(AuthUrlClient.class);
045
046    static private Class<? extends Authenticator> AuthenticatorClass = null;
047
048    static private String errorMsg = null;
049
050    static {
051        try {
052            AuthenticatorClass = determineAuthenticatorClassType();
053        }
054        catch (Exception e) {
055            errorMsg = e.getMessage();
056        }
057    }
058
059    private static HttpURLConnection getConnection(URL url) throws IOException {
060        AuthenticatedURL.Token token = new AuthenticatedURL.Token();
061        HttpURLConnection conn;
062        try {
063            conn = new AuthenticatedURL(AuthenticatorClass.newInstance()).openConnection(url, token);
064        }
065        catch (AuthenticationException ex) {
066            throw new IOException("Could not authenticate, " + ex.getMessage(), ex);
067        }
068        catch (InstantiationException ex) {
069            throw new IOException("Could not authenticate, " + ex.getMessage(), ex);
070        }
071        catch (IllegalAccessException ex) {
072            throw new IOException("Could not authenticate, " + ex.getMessage(), ex);
073        }
074        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
075            throw new IOException("Unexpected response code [" + conn.getResponseCode() + "], message ["
076                    + conn.getResponseMessage() + "]");
077        }
078        return conn;
079    }
080
081    @SuppressWarnings("unchecked")
082    private static Class<? extends Authenticator> determineAuthenticatorClassType() throws Exception {
083        // Adapted from
084        // org.apache.hadoop.security.authentication.server.AuthenticationFilter#init
085        Class<? extends Authenticator> authClass;
086        String authName = ConfigurationService.get(SERVER_SERVER_AUTH_TYPE);
087
088        LOG.info("Oozie server-server authentication is " + authName);
089
090        String authClassName;
091        if (authName == null) {
092            throw new IOException("Authentication type must be specified: simple|kerberos|<class>");
093        }
094        authName = authName.trim();
095        if (authName.equals("simple")) {
096            authClassName = PseudoAuthenticator.class.getName();
097        }
098        else if (authName.equals("kerberos")) {
099            authClassName = KerberosAuthenticator.class.getName();
100        }
101        else {
102            authClassName = authName;
103        }
104
105        authClass = (Class<? extends Authenticator>) Thread.currentThread().getContextClassLoader()
106                .loadClass(authClassName);
107        return authClass;
108    }
109
110    /**
111     * Calls other Oozie server over HTTP.
112     *
113     * @param server The URL of the other Oozie server
114     * @return BufferedReader of inputstream.
115     * @throws IOException Signals that an I/O exception has occurred.
116     */
117    public static BufferedReader callServer(String server) throws IOException {
118
119        if (AuthenticatorClass == null) {
120            throw new IOException(errorMsg);
121        }
122
123        final URL url = new URL(server);
124        BufferedReader reader = null;
125        try {
126            reader = UserGroupInformation.getLoginUser().doAs(new PrivilegedExceptionAction<BufferedReader>() {
127                @Override
128                public BufferedReader run() throws IOException {
129                    HttpURLConnection conn = getConnection(url);
130                    BufferedReader reader = null;
131                    if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
132                        InputStream is = conn.getInputStream();
133                        reader = new BufferedReader(new InputStreamReader(is));
134                    }
135                    return reader;
136                }
137            });
138        }
139        catch (InterruptedException ie) {
140            throw new IOException(ie);
141        }
142        return reader;
143    }
144
145    public static String getQueryParamString(Map<String, String[]> params) {
146        StringBuilder stringBuilder = new StringBuilder();
147        if (params == null || params.isEmpty()) {
148            return "";
149        }
150        for (String key : params.keySet()) {
151            if (!key.isEmpty() && params.get(key).length > 0) {
152                stringBuilder.append("&");
153                String value = params.get(key)[0]; // We don't support multi value.
154                stringBuilder.append(key);
155                stringBuilder.append("=");
156                stringBuilder.append(value);
157            }
158        }
159        return stringBuilder.toString();
160    }
161
162}