You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mp...@apache.org on 2014/01/23 17:30:13 UTC
git commit: AMBARI-4335. Configure Jetty to return errors as JSON.
(mpapirkovskyy)
Updated Branches:
refs/heads/trunk 49de3a349 -> 90f00a2a4
AMBARI-4335. Configure Jetty to return errors as JSON. (mpapirkovskyy)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/90f00a2a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/90f00a2a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/90f00a2a
Branch: refs/heads/trunk
Commit: 90f00a2a4267a7a94e8c89ade790ca7b71d8199a
Parents: 49de3a3
Author: Myroslav Papirkovskyy <mp...@hortonworks.com>
Authored: Thu Jan 23 18:28:01 2014 +0200
Committer: Myroslav Papirkovskyy <mp...@hortonworks.com>
Committed: Thu Jan 23 18:28:01 2014 +0200
----------------------------------------------------------------------
.../ambari/server/api/AmbariErrorHandler.java | 62 +++++++++++
.../ambari/server/controller/AmbariServer.java | 3 +
.../server/controller/ControllerModule.java | 3 +
.../server/api/AmbariErrorHandlerTest.java | 104 +++++++++++++++++++
4 files changed, 172 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/90f00a2a/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariErrorHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariErrorHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariErrorHandler.java
new file mode 100644
index 0000000..ee4e56f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariErrorHandler.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ambari.server.api;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class AmbariErrorHandler extends ErrorHandler {
+ private final Gson gson;
+
+ @Inject
+ public AmbariErrorHandler(@Named("prettyGson") Gson prettyGson) {
+ this.gson = prettyGson;
+ }
+
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
+ connection.getRequest().setHandled(true);
+
+ response.setContentType(MimeTypes.TEXT_PLAIN);
+
+ Map<String, Object> errorMap = new LinkedHashMap<String, Object>();
+ int code = connection.getResponse().getStatus();
+ errorMap.put("status", code);
+ String message = connection.getResponse().getReason();
+ if (message == null) {
+ message = HttpStatus.getMessage(code);
+ }
+ errorMap.put("message", message);
+
+ gson.toJson(errorMap, response.getWriter());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/90f00a2a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index e745994..00f1b74 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -31,6 +31,7 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.agent.HeartBeatHandler;
import org.apache.ambari.server.agent.rest.AgentResource;
+import org.apache.ambari.server.api.AmbariErrorHandler;
import org.apache.ambari.server.api.AmbariPersistFilter;
import org.apache.ambari.server.api.rest.BootStrapResource;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -167,6 +168,8 @@ public class AmbariServer {
ServletContextHandler root = new ServletContextHandler(server, CONTEXT_PATH,
ServletContextHandler.SECURITY | ServletContextHandler.SESSIONS);
+ root.setErrorHandler(injector.getInstance(AmbariErrorHandler.class));
+
//Changing session cookie name to avoid conflicts
root.getSessionHandler().getSessionManager().setSessionCookie("AMBARISESSIONID");
http://git-wip-us.apache.org/repos/asf/ambari/blob/90f00a2a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 2b93e54..adb78c3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -76,6 +76,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
+import com.google.gson.GsonBuilder;
import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_JDBC_DDL_FILE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_ONLY;
import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_OR_EXTEND;
@@ -98,6 +99,7 @@ public class ControllerModule extends AbstractModule {
private final Configuration configuration;
private final HostsMap hostsMap;
private boolean dbInitNeeded;
+ private final Gson prettyGson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
public ControllerModule() throws Exception {
configuration = new Configuration();
@@ -116,6 +118,7 @@ public class ControllerModule extends AbstractModule {
bind(Configuration.class).toInstance(configuration);
bind(HostsMap.class).toInstance(hostsMap);
bind(PasswordEncoder.class).toInstance(new StandardPasswordEncoder());
+ bind(Gson.class).annotatedWith(Names.named("prettyGson")).toInstance(prettyGson);
install(buildJpaPersistModule());
http://git-wip-us.apache.org/repos/asf/ambari/blob/90f00a2a/ambari-server/src/test/java/org/apache/ambari/server/api/AmbariErrorHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/AmbariErrorHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/AmbariErrorHandlerTest.java
new file mode 100644
index 0000000..fb41f6e
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/AmbariErrorHandlerTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.ambari.server.api;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.sun.jersey.api.client.*;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.junit.Test;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class AmbariErrorHandlerTest {
+ Gson gson = new Gson();
+
+
+ @Test
+ public void testHandle() throws Exception {
+
+ }
+
+ @Test
+ public void testErrorWithJetty() throws Exception {
+ Server server = new Server(0);
+
+ ServletContextHandler root = new ServletContextHandler(server, "/",
+ ServletContextHandler.SECURITY | ServletContextHandler.SESSIONS);
+
+ root.addServlet(HelloServlet.class, "/hello");
+ root.addServlet(DefaultServlet.class, "/");
+ root.setErrorHandler(new AmbariErrorHandler(gson));
+
+ server.start();
+
+ int localPort = server.getConnectors()[0].getLocalPort();
+
+ Client client = new Client();
+ WebResource resource = client.resource("http://localhost:" + localPort + "/");
+
+
+ ClientResponse successResponse = resource.path("hello").get(ClientResponse.class);
+ assertEquals(HttpServletResponse.SC_OK, successResponse.getStatus());
+
+ ClientResponse failResponse = resource.path("fail").get(ClientResponse.class);
+
+ assertEquals(HttpServletResponse.SC_NOT_FOUND, failResponse.getStatus());
+
+ try {
+ String response = failResponse.getEntity(String.class);
+ System.out.println(response);
+ Map map;
+ map = gson.fromJson(response, Map.class);
+ System.out.println(map);
+ assertNotNull("Incorrect response status", map.get("status"));
+ assertNotNull("Incorrect response message", map.get("message"));
+ } catch (JsonSyntaxException e1) {
+ fail("Incorrect response");
+ }
+
+
+ server.stop();
+ }
+
+
+ @SuppressWarnings("serial")
+ public static class HelloServlet extends HttpServlet {
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ response.setContentType("text/html");
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.getWriter().println("hello");
+ }
+
+ }
+}