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 */ 018package org.apache.hadoop.fs.http.client; 019 020import org.apache.commons.io.Charsets; 021import org.apache.hadoop.classification.InterfaceAudience; 022import org.apache.hadoop.fs.Path; 023import org.json.simple.parser.JSONParser; 024import org.json.simple.parser.ParseException; 025 026import java.io.IOException; 027import java.io.InputStreamReader; 028import java.net.HttpURLConnection; 029import java.net.URI; 030import java.net.URL; 031import java.net.URLEncoder; 032import java.text.MessageFormat; 033import java.util.List; 034import java.util.Map; 035 036/** 037 * Utility methods used by HttpFS classes. 038 */ 039@InterfaceAudience.Private 040public class HttpFSUtils { 041 042 public static final String SERVICE_NAME = "/webhdfs"; 043 044 public static final String SERVICE_VERSION = "/v1"; 045 046 private static final String SERVICE_PATH = SERVICE_NAME + SERVICE_VERSION; 047 048 /** 049 * Convenience method that creates an HTTP <code>URL</code> for the 050 * HttpFSServer file system operations. 051 * <p/> 052 * 053 * @param path the file path. 054 * @param params the query string parameters. 055 * 056 * @return a <code>URL</code> for the HttpFSServer server, 057 * 058 * @throws IOException thrown if an IO error occurs. 059 */ 060 static URL createURL(Path path, Map<String, String> params) 061 throws IOException { 062 return createURL(path, params, null); 063 } 064 065 /** 066 * Convenience method that creates an HTTP <code>URL</code> for the 067 * HttpFSServer file system operations. 068 * <p/> 069 * 070 * @param path the file path. 071 * @param params the query string parameters. 072 * @param multiValuedParams multi valued parameters of the query string 073 * 074 * @return URL a <code>URL</code> for the HttpFSServer server, 075 * 076 * @throws IOException thrown if an IO error occurs. 077 */ 078 static URL createURL(Path path, Map<String, String> params, Map<String, 079 List<String>> multiValuedParams) throws IOException { 080 URI uri = path.toUri(); 081 String realScheme; 082 if (uri.getScheme().equalsIgnoreCase(HttpFSFileSystem.SCHEME)) { 083 realScheme = "http"; 084 } else if (uri.getScheme().equalsIgnoreCase(HttpsFSFileSystem.SCHEME)) { 085 realScheme = "https"; 086 087 } else { 088 throw new IllegalArgumentException(MessageFormat.format( 089 "Invalid scheme [{0}] it should be '" + HttpFSFileSystem.SCHEME + "' " + 090 "or '" + HttpsFSFileSystem.SCHEME + "'", uri)); 091 } 092 StringBuilder sb = new StringBuilder(); 093 sb.append(realScheme).append("://").append(uri.getAuthority()). 094 append(SERVICE_PATH).append(uri.getPath()); 095 096 String separator = "?"; 097 for (Map.Entry<String, String> entry : params.entrySet()) { 098 sb.append(separator).append(entry.getKey()).append("="). 099 append(URLEncoder.encode(entry.getValue(), "UTF8")); 100 separator = "&"; 101 } 102 if (multiValuedParams != null) { 103 for (Map.Entry<String, List<String>> multiValuedEntry : 104 multiValuedParams.entrySet()) { 105 String name = URLEncoder.encode(multiValuedEntry.getKey(), "UTF8"); 106 List<String> values = multiValuedEntry.getValue(); 107 for (String value : values) { 108 sb.append(separator).append(name).append("="). 109 append(URLEncoder.encode(value, "UTF8")); 110 separator = "&"; 111 } 112 } 113 } 114 return new URL(sb.toString()); 115 } 116 117 /** 118 * Convenience method that JSON Parses the <code>InputStream</code> of a 119 * <code>HttpURLConnection</code>. 120 * 121 * @param conn the <code>HttpURLConnection</code>. 122 * 123 * @return the parsed JSON object. 124 * 125 * @throws IOException thrown if the <code>InputStream</code> could not be 126 * JSON parsed. 127 */ 128 static Object jsonParse(HttpURLConnection conn) throws IOException { 129 try { 130 JSONParser parser = new JSONParser(); 131 return parser.parse(new InputStreamReader(conn.getInputStream(), Charsets.UTF_8)); 132 } catch (ParseException ex) { 133 throw new IOException("JSON parser error, " + ex.getMessage(), ex); 134 } 135 } 136}