Java tutorial
/** * 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.hadoop.hdfs.server.namenode; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_SECONDARY_NAMENODE_KRB_HTTPS_USER_NAME_KEY; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_SECONDARY_NAMENODE_USER_NAME_KEY; import java.io.IOException; import java.security.PrivilegedExceptionAction; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.hadoop.security.SecurityUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.StringUtils; /** * This class is used in Namesystem's jetty to retrieve a file. * Typically used by the Secondary NameNode to retrieve image and * edit file for periodic checkpointing. */ public class GetImageServlet extends HttpServlet { private static final long serialVersionUID = -7669068179452648952L; private static final Log LOG = LogFactory.getLog(GetImageServlet.class); @SuppressWarnings("unchecked") public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { Map<String, String[]> pmap = request.getParameterMap(); try { ServletContext context = getServletContext(); final FSImage nnImage = (FSImage) context.getAttribute("name.system.image"); final TransferFsImage ff = new TransferFsImage(pmap, request, response); final Configuration conf = (Configuration) getServletContext().getAttribute(JspHelper.CURRENT_CONF); if (UserGroupInformation.isSecurityEnabled() && !isValidRequestor(request.getRemoteUser(), conf)) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "Only Namenode and Secondary Namenode may access this servlet"); LOG.warn("Received non-NN/SNN request for image or edits from " + request.getRemoteHost()); return; } UserGroupInformation.getCurrentUser().doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { if (ff.getImage()) { // send fsImage TransferFsImage.getFileServer(response.getOutputStream(), nnImage.getFsImageName()); } else if (ff.getEdit()) { // send edits TransferFsImage.getFileServer(response.getOutputStream(), nnImage.getFsEditName()); } else if (ff.putImage()) { // issue a HTTP get request to download the new fsimage nnImage.validateCheckpointUpload(ff.getToken()); reloginIfNecessary().doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { TransferFsImage.getFileClient(ff.getInfoServer(), "getimage=1", nnImage.getFsImageNameCheckpoint()); return null; } }); nnImage.checkpointUploadDone(); } return null; } // We may have lost our ticket since the last time we tried to open // an http connection, so log in just in case. private UserGroupInformation reloginIfNecessary() throws IOException { // This method is only called on the NN, therefore it is safe to // use these key values. return UserGroupInformation.loginUserFromKeytabAndReturnUGI( SecurityUtil.getServerPrincipal(conf.get(DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY), NameNode.getAddress(conf).getHostName()), conf.get(DFSConfigKeys.DFS_NAMENODE_KEYTAB_FILE_KEY)); } }); } catch (Exception ie) { String errMsg = "GetImage failed. " + StringUtils.stringifyException(ie); response.sendError(HttpServletResponse.SC_GONE, errMsg); throw new IOException(errMsg); } finally { response.getOutputStream().close(); } } private boolean isValidRequestor(String remoteUser, Configuration conf) throws IOException { if (remoteUser == null) { // This really shouldn't happen... LOG.warn("Received null remoteUser while authorizing access to getImage servlet"); return false; } String[] validRequestors = { SecurityUtil.getServerPrincipal(conf.get(DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY), NameNode.getAddress(conf).getHostName()), SecurityUtil.getServerPrincipal(conf.get(DFS_NAMENODE_USER_NAME_KEY), NameNode.getAddress(conf).getHostName()), SecurityUtil.getServerPrincipal(conf.get(DFS_SECONDARY_NAMENODE_KRB_HTTPS_USER_NAME_KEY), SecondaryNameNode.getHttpAddress(conf).getHostName()), SecurityUtil.getServerPrincipal(conf.get(DFS_SECONDARY_NAMENODE_USER_NAME_KEY), SecondaryNameNode.getHttpAddress(conf).getHostName()) }; for (String v : validRequestors) { if (v != null && v.equals(remoteUser)) { if (LOG.isDebugEnabled()) LOG.debug("isValidRequestor is allowing: " + remoteUser); return true; } } if (LOG.isDebugEnabled()) LOG.debug("isValidRequestor is rejecting: " + remoteUser); return false; } }