Skip to content

Commit c0bb774

Browse files
committed
Copy files with (minimal changes, not everything) conflicting with javax/jakarta usage in hadoop/hbase. This would be needed if hadoop moves to jakarta in future. This is done proactively based on an internal private change we have for hadoop with jetty12 + ee10. The impacted files are identified based on diff files for the internal PR as shown in check_hadoop_jakarta_impact.sh. We will drop this script in next commit. Just for ref added here.
1 parent e90af6b commit c0bb774

File tree

7 files changed

+663
-2
lines changed

7 files changed

+663
-2
lines changed

check_hadoop_jakarta_impact.sh

Lines changed: 399 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.util;
19+
20+
import org.apache.hadoop.util.JsonSerialization;
21+
import org.apache.yetus.audience.InterfaceAudience;
22+
import org.apache.yetus.audience.InterfaceStability;
23+
24+
import javax.servlet.http.HttpServletResponse;
25+
import java.io.IOException;
26+
import java.io.Writer;
27+
import java.util.Collections;
28+
import java.util.LinkedHashMap;
29+
import java.util.Map;
30+
31+
/**
32+
* HTTP utility class to help propagate server side exception to the client
33+
* over HTTP as a JSON payload.
34+
* <p>
35+
* It creates HTTP Servlet and JAX-RPC error responses including details of the
36+
* exception that allows a client to recreate the remote exception.
37+
* <p>
38+
* It parses HTTP client connections and recreates the exception.
39+
*/
40+
@InterfaceAudience.Private
41+
@InterfaceStability.Unstable
42+
public class HttpExceptionUtils {
43+
44+
public static final String ERROR_JSON = "RemoteException";
45+
public static final String ERROR_EXCEPTION_JSON = "exception";
46+
public static final String ERROR_CLASSNAME_JSON = "javaClassName";
47+
public static final String ERROR_MESSAGE_JSON = "message";
48+
49+
private static final String APPLICATION_JSON_MIME = "application/json";
50+
51+
private static final String ENTER = System.getProperty("line.separator");
52+
53+
/**
54+
* Creates a HTTP servlet response serializing the exception in it as JSON.
55+
*
56+
* @param response the servlet response
57+
* @param status the error code to set in the response
58+
* @param ex the exception to serialize in the response
59+
* @throws IOException thrown if there was an error while creating the
60+
* response
61+
*/
62+
public static void createServletExceptionResponse(
63+
HttpServletResponse response, int status, Throwable ex)
64+
throws IOException {
65+
response.setStatus(status);
66+
response.setContentType(APPLICATION_JSON_MIME);
67+
Map<String, Object> json = new LinkedHashMap<String, Object>();
68+
json.put(ERROR_MESSAGE_JSON, getOneLineMessage(ex));
69+
json.put(ERROR_EXCEPTION_JSON, ex.getClass().getSimpleName());
70+
json.put(ERROR_CLASSNAME_JSON, ex.getClass().getName());
71+
Map<String, Object> jsonResponse =
72+
Collections.singletonMap(ERROR_JSON, json);
73+
Writer writer = response.getWriter();
74+
JsonSerialization.writer().writeValue(writer, jsonResponse);
75+
writer.flush();
76+
}
77+
78+
private static String getOneLineMessage(Throwable exception) {
79+
String message = exception.getMessage();
80+
if (message != null) {
81+
int i = message.indexOf(ENTER);
82+
if (i > -1) {
83+
message = message.substring(0, i);
84+
}
85+
}
86+
return message;
87+
}
88+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.util;
19+
20+
import java.io.*;
21+
import java.util.Calendar;
22+
23+
import javax.servlet.*;
24+
import javax.servlet.http.HttpServletRequest;
25+
26+
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
27+
import org.apache.yetus.audience.InterfaceAudience;
28+
import org.apache.yetus.audience.InterfaceStability;
29+
30+
@InterfaceAudience.Private
31+
@InterfaceStability.Unstable
32+
public class ServletUtil {
33+
/**
34+
* Initial HTML header.
35+
*
36+
* @param response response.
37+
* @param title title.
38+
* @throws IOException raised on errors performing I/O.
39+
* @return PrintWriter.
40+
*/
41+
public static PrintWriter initHTML(ServletResponse response, String title
42+
) throws IOException {
43+
response.setContentType("text/html");
44+
PrintWriter out = response.getWriter();
45+
out.println("<html>\n"
46+
+ "<link rel='stylesheet' type='text/css' href='/static/hadoop.css'>\n"
47+
+ "<title>" + title + "</title>\n"
48+
+ "<body>\n"
49+
+ "<h1>" + title + "</h1>\n");
50+
return out;
51+
}
52+
53+
/**
54+
* Get a parameter from a ServletRequest.
55+
* Return null if the parameter contains only white spaces.
56+
*
57+
* @param request request.
58+
* @param name name.
59+
* @return get a parameter from a ServletRequest.
60+
*/
61+
public static String getParameter(ServletRequest request, String name) {
62+
String s = request.getParameter(name);
63+
if (s == null) {
64+
return null;
65+
}
66+
s = s.trim();
67+
return s.length() == 0? null: s;
68+
}
69+
70+
/**
71+
* parseLongParam.
72+
*
73+
* @param request request.
74+
* @param param param.
75+
* @return a long value as passed in the given parameter, throwing
76+
* an exception if it is not present or if it is not a valid number.
77+
* @throws IOException raised on errors performing I/O.
78+
*/
79+
public static long parseLongParam(ServletRequest request, String param)
80+
throws IOException {
81+
String paramStr = request.getParameter(param);
82+
if (paramStr == null) {
83+
throw new IOException("Invalid request has no " + param + " parameter");
84+
}
85+
86+
return Long.parseLong(paramStr);
87+
}
88+
89+
public static final String HTML_TAIL = "<hr />\n"
90+
+ "<a href='http://hadoop.apache.org'>Hadoop</a>, "
91+
+ Calendar.getInstance().get(Calendar.YEAR) + ".\n"
92+
+ "</body></html>";
93+
94+
/**
95+
* HTML footer to be added in the jsps.
96+
* @return the HTML footer.
97+
*/
98+
public static String htmlFooter() {
99+
return HTML_TAIL;
100+
}
101+
102+
/**
103+
* Parse the path component from the given request and return w/o decoding.
104+
* @param request Http request to parse
105+
* @param servletName the name of servlet that precedes the path
106+
* @return path component, null if the default charset is not supported
107+
*/
108+
public static String getRawPath(final HttpServletRequest request, String servletName) {
109+
Preconditions.checkArgument(request.getRequestURI().startsWith(servletName+"/"));
110+
return request.getRequestURI().substring(servletName.length());
111+
}
112+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.util;
19+
20+
import com.fasterxml.jackson.databind.ObjectMapper;
21+
import org.junit.Assert;
22+
import org.junit.Test;
23+
import org.mockito.Mockito;
24+
25+
import javax.servlet.http.HttpServletResponse;
26+
import java.io.IOException;
27+
import java.io.PrintWriter;
28+
import java.io.StringWriter;
29+
import java.util.Map;
30+
31+
public class TestHttpExceptionUtils {
32+
33+
@Test
34+
public void testCreateServletException() throws IOException {
35+
StringWriter writer = new StringWriter();
36+
PrintWriter printWriter = new PrintWriter(writer);
37+
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
38+
Mockito.when(response.getWriter()).thenReturn(printWriter);
39+
int status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
40+
Exception ex = new IOException("Hello IOEX");
41+
HttpExceptionUtils.createServletExceptionResponse(response, status, ex);
42+
Mockito.verify(response).setStatus(status);
43+
Mockito.verify(response).setContentType(Mockito.eq("application/json"));
44+
ObjectMapper mapper = new ObjectMapper();
45+
Map json = mapper.readValue(writer.toString(), Map.class);
46+
json = (Map) json.get(HttpExceptionUtils.ERROR_JSON);
47+
Assert.assertEquals(IOException.class.getName(),
48+
json.get(HttpExceptionUtils.ERROR_CLASSNAME_JSON));
49+
Assert.assertEquals(IOException.class.getSimpleName(),
50+
json.get(HttpExceptionUtils.ERROR_EXCEPTION_JSON));
51+
Assert.assertEquals("Hello IOEX",
52+
json.get(HttpExceptionUtils.ERROR_MESSAGE_JSON));
53+
}
54+
}

hbase-http/src/main/java/org/apache/hadoop/hbase/http/ProxyUserAuthenticationFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import org.apache.hadoop.hbase.security.authentication.server.AuthenticationFilter;
3737
import org.apache.hadoop.security.authorize.AuthorizationException;
3838
import org.apache.hadoop.security.authorize.ProxyUsers;
39-
import org.apache.hadoop.util.HttpExceptionUtils;
39+
import org.apache.hadoop.hbase.util.HttpExceptionUtils;
4040
import org.apache.hadoop.util.StringUtils;
4141
import org.apache.yetus.audience.InterfaceAudience;
4242
import org.apache.yetus.audience.InterfaceStability;

hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
4242
import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
4343
import org.apache.hadoop.security.ssl.SSLFactory;
44-
import org.apache.hadoop.util.ServletUtil;
44+
import org.apache.hadoop.hbase.util.ServletUtil;
4545
import org.apache.hadoop.util.Tool;
4646
import org.apache.yetus.audience.InterfaceAudience;
4747
import org.slf4j.Logger;

hbase-mapreduce/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@
309309
<artifactId>javax.ws.rs-api</artifactId>
310310
<scope>test</scope>
311311
</dependency>
312+
<!-- NOTE: We use this in test i.e. TestTableOutputFormat, hence added as a dependency here.
313+
Also, we would need to move this to jakarta with EE10 most probably! -->
314+
<dependency>
315+
<groupId>javax.validation</groupId>
316+
<artifactId>validation-api</artifactId>
317+
<version>2.0.1.Final</version>
318+
<scope>test</scope>
319+
</dependency>
312320
<dependency>
313321
<!--maven dependency:analyze says not needed but tests fail w/o-->
314322
<groupId>org.apache.hadoop</groupId>

0 commit comments

Comments
 (0)