FELIX-3684 Add Http Service web console plugin (patch by Chetan Mehrotra, thanks alot)
(plus fixed the http.api dependency to the latest release 2.2.0)
(plus updated OSGi Core dependency to 4.2.0 I think this is reasonable)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1391181 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/pom.xml b/http/base/pom.xml
index b27c5df..3ba340a 100644
--- a/http/base/pom.xml
+++ b/http/base/pom.xml
@@ -59,6 +59,7 @@
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
+ <version>4.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -69,7 +70,7 @@
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix.http.api</artifactId>
- <version>${pom.version}</version>
+ <version>2.2.0</version>
</dependency>
</dependencies>
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
index 7abbedd..dfab10a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
@@ -23,6 +23,7 @@
import org.apache.felix.http.api.ExtHttpService;
import org.apache.felix.http.base.internal.dispatch.Dispatcher;
import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+import org.apache.felix.http.base.internal.handler.HttpServicePlugin;
import org.apache.felix.http.base.internal.listener.HttpSessionAttributeListenerManager;
import org.apache.felix.http.base.internal.listener.HttpSessionListenerManager;
import org.apache.felix.http.base.internal.listener.ServletContextAttributeListenerManager;
@@ -65,6 +66,7 @@
private final HttpSessionListenerManager sessionListener;
private final HttpSessionAttributeListenerManager sessionAttributeListener;
private final boolean sharedContextAttributes;
+ private final HttpServicePlugin plugin;
private ServiceRegistration serviceReg;
public HttpServiceController(BundleContext bundleContext)
@@ -79,6 +81,7 @@
this.sessionListener = new HttpSessionListenerManager(bundleContext);
this.sessionAttributeListener = new HttpSessionAttributeListenerManager(bundleContext);
this.sharedContextAttributes = getBoolean(FELIX_HTTP_SHARED_SERVLET_CONTEXT_ATTRIBUTES);
+ this.plugin = new HttpServicePlugin(bundleContext,registry);
}
public Dispatcher getDispatcher()
@@ -128,6 +131,7 @@
this.requestAttributeListener.open();
this.sessionListener.open();
this.sessionAttributeListener.open();
+ this.plugin.register();
HttpServiceFactory factory = new HttpServiceFactory(servletContext, this.registry,
this.contextAttributeListener, this.sharedContextAttributes);
@@ -146,6 +150,7 @@
this.contextAttributeListener.close();
this.requestListener.close();
this.requestAttributeListener.close();
+ this.plugin.unregister();
try {
this.serviceReg.unregister();
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
index 400fe45..33bee18 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
@@ -93,4 +93,14 @@
{
return other.ranking - this.ranking;
}
+
+ public int getRanking()
+ {
+ return ranking;
+ }
+
+ public String getPattern()
+ {
+ return regex.toString();
+ }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java
new file mode 100644
index 0000000..d1d0aae
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java
@@ -0,0 +1,227 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceRegistration;
+
+import javax.servlet.Servlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Properties;
+
+@SuppressWarnings("serial")
+public class HttpServicePlugin extends HttpServlet
+{
+
+ private final HandlerRegistry registry;
+ private final BundleContext context;
+
+ private ServiceRegistration serviceReg;
+
+ public HttpServicePlugin(BundleContext context, HandlerRegistry registry)
+ {
+ this.registry = registry;
+ this.context = context;
+ }
+
+ public void register()
+ {
+ Properties props = new Properties();
+ props.put(Constants.SERVICE_VENDOR, "Apache Software Foundation");
+ props.put(Constants.SERVICE_DESCRIPTION, "HTTP Service Web Console Plugin");
+ props.put("felix.webconsole.label", "httpservice");
+ props.put("felix.webconsole.title", "HTTP Service");
+ props.put("felix.webconsole.configprinter.modes", "always");
+ this.serviceReg = context.registerService(Servlet.class.getName(), this, props);
+ }
+
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException
+ {
+ getHtml(resp);
+ }
+
+ private void getHtml(HttpServletResponse resp) throws IOException
+ {
+ final PrintWriter pw = resp.getWriter();
+
+ printServletDetails(pw);
+ printFilterDetails(pw);
+
+ }
+
+ private void printFilterDetails(PrintWriter pw)
+ {
+ pw.println("<p class=\"statline ui-state-highlight\">${Registered Filter Services}</p>");
+
+ pw.println("<table class=\"nicetable\">");
+ pw.println("<thead><tr>");
+ pw.println("<th class=\"header\">${Pattern}</th>");
+ pw.println("<th class=\"header\">${Filter(Ranking)}</th>");
+ pw.println("<th class=\"header\">${Bundle}</th>");
+ pw.println("</tr></thead>");
+
+ FilterHandler[] filters = registry.getFilters();
+ Arrays.sort(filters);
+ String rowClass = "odd";
+ for (FilterHandler filter : filters)
+ {
+ pw.println("<tr class=\"" + rowClass + " ui-state-default\">");
+ pw.println("<td>" + filter.getPattern() + "</td>");
+ pw.println("<td>" + filter.getFilter().getClass().getName() + "(" + filter.getRanking() + ")" + "</td>");
+
+ printBundleDetails(pw, filter.getFilter().getClass());
+
+ if (rowClass.equals("odd"))
+ {
+ rowClass = "even";
+ }
+ else
+ {
+ rowClass = "odd";
+ }
+ }
+ pw.println("</table>");
+ }
+
+ private void printServletDetails(PrintWriter pw)
+ {
+ pw.println("<p class=\"statline ui-state-highlight\">${Registered Servlet Services}</p>");
+
+ pw.println("<table class=\"nicetable\">");
+ pw.println("<thead><tr>");
+ pw.println("<th class=\"header\">${Alias}</th>");
+ pw.println("<th class=\"header\">${Servlet}</th>");
+ pw.println("<th class=\"header\">${Bundle}</th>");
+ pw.println("</tr></thead>");
+
+ ServletHandler[] servlets = registry.getServlets();
+ String rowClass = "odd";
+ for (ServletHandler servlet : servlets)
+ {
+
+ pw.println("<tr class=\"" + rowClass + " ui-state-default\">");
+ pw.println("<td>" + servlet.getAlias() + "</td>");
+ pw.println("<td>" + servlet.getServlet().getClass().getName() + "</td>");
+
+ printBundleDetails(pw, servlet.getServlet().getClass());
+
+ pw.println("</tr>");
+ if (rowClass.equals("odd"))
+ {
+ rowClass = "even";
+ }
+ else
+ {
+ rowClass = "odd";
+ }
+ }
+ pw.println("</table>");
+ }
+
+ /**
+ * @see org.apache.felix.webconsole.ConfigurationPrinter#printConfiguration(java.io.PrintWriter)
+ */
+ public void printConfiguration(final PrintWriter pw)
+ {
+ pw.println("HTTP Service Details:");
+ pw.println();
+ pw.println("Registered Servlet Services");
+ ServletHandler[] servlets = registry.getServlets();
+ for (ServletHandler servlet : servlets)
+ {
+ pw.println("Alias : " + servlet.getAlias());
+
+ addSpace(pw, 1);
+ pw.println("Class :" + servlet.getServlet().getClass().getName());
+ addSpace(pw, 1);
+ pw.println("Bundle :" + getBundleDetails(servlet.getServlet().getClass()));
+
+ }
+
+ pw.println();
+
+ pw.println("Registered Filter Services");
+ FilterHandler[] filters = registry.getFilters();
+ Arrays.sort(filters);
+ for (FilterHandler filter : filters)
+ {
+ pw.println("Pattern : " + filter.getPattern());
+
+ addSpace(pw, 1);
+ pw.println("Ranking :" + filter.getRanking());
+ addSpace(pw, 1);
+ pw.println("Class :" + filter.getFilter().getClass().getName());
+ addSpace(pw, 1);
+ pw.println("Bundle :" + getBundleDetails(filter.getFilter().getClass()));
+ }
+ }
+
+ public void unregister()
+ {
+ if (this.serviceReg != null)
+ {
+ this.serviceReg.unregister();
+ }
+ }
+
+ private void printBundleDetails(PrintWriter pw, Class<?> c)
+ {
+ Bundle b = getBundle(c);
+ pw.println("<td>");
+ if (b == null)
+ {
+ pw.print("UNKNOWN");
+ }
+ else
+ {
+ String details = b.getSymbolicName();
+ pw.print("<a href=\"${appRoot}/bundles/" + b.getBundleId() + "\">" + details + "</a>");
+ }
+ pw.println("</td>");
+ }
+
+ private String getBundleDetails(Class<?> c)
+ {
+ Bundle b = getBundle(c);
+ return (b == null) ? "UNKNOWN" : b.getSymbolicName();
+ }
+
+ private static void addSpace(PrintWriter pw, int count)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ pw.print(" ");
+ }
+ }
+
+ private Bundle getBundle(Class<?> clazz)
+ {
+ return FrameworkUtil.getBundle(clazz);
+ }
+}