Merge branch 'master' into release
This commit is contained in:
commit
0f77ee6b34
|
@ -113,7 +113,12 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
|
||||||
_httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
|
_httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
|
||||||
_connectingChannels.put(channel,connectTimeout);
|
_connectingChannels.put(channel,connectTimeout);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (UnresolvedAddressException ex)
|
||||||
|
{
|
||||||
|
if (channel != null)
|
||||||
|
channel.close();
|
||||||
|
destination.onConnectionFailed(ex);
|
||||||
}
|
}
|
||||||
catch(IOException ex)
|
catch(IOException ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<parent>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-project</artifactId>
|
||||||
|
<version>7.5.3-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>jetty-http-spi</artifactId>
|
||||||
|
<name>Jetty :: Http Service Provider Interface</name>
|
||||||
|
<properties>
|
||||||
|
<bundle-symbolic-name>${project.groupId}.http.spi</bundle-symbolic-name>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.net.httpserver</groupId>
|
||||||
|
<artifactId>http</artifactId>
|
||||||
|
<version>20070405</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-server</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>manifest</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>artifact-jar</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>findbugs-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<onlyAnalyze>org.eclipse.jetty.http.spi.*</onlyAnalyze>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,121 @@
|
||||||
|
package org.eclipse.jetty.http.spi;
|
||||||
|
//========================================================================
|
||||||
|
//Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//All rights reserved. This program and the accompanying materials
|
||||||
|
//are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
//and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//The Eclipse Public License is available at
|
||||||
|
//http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//The Apache License v2.0 is available at
|
||||||
|
//http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//You may elect to redistribute this code under either of these licenses.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.Authenticator;
|
||||||
|
import com.sun.net.httpserver.Authenticator.Result;
|
||||||
|
import com.sun.net.httpserver.HttpContext;
|
||||||
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
import com.sun.net.httpserver.HttpPrincipal;
|
||||||
|
import org.eclipse.jetty.server.HttpConnection;
|
||||||
|
import org.eclipse.jetty.server.Request;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty handler that bridges requests to {@link HttpHandler}.
|
||||||
|
*/
|
||||||
|
public class HttpSpiContextHandler extends ContextHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
private HttpContext _httpContext;
|
||||||
|
|
||||||
|
private HttpHandler _httpHandler;
|
||||||
|
|
||||||
|
|
||||||
|
public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler)
|
||||||
|
{
|
||||||
|
this._httpContext = httpContext;
|
||||||
|
this._httpHandler = httpHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
|
||||||
|
{
|
||||||
|
if (!target.startsWith(getContextPath())) return;
|
||||||
|
|
||||||
|
JettyHttpExchange jettyHttpExchange = new JettyHttpExchange(_httpContext, req, resp);
|
||||||
|
|
||||||
|
// TODO: add filters processing
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Authenticator auth = _httpContext.getAuthenticator();
|
||||||
|
if (auth != null)
|
||||||
|
handleAuthentication(resp, jettyHttpExchange, auth);
|
||||||
|
else
|
||||||
|
_httpHandler.handle(jettyHttpExchange);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody());
|
||||||
|
|
||||||
|
resp.setStatus(500);
|
||||||
|
writer.println("<h2>HTTP ERROR: 500</h2>");
|
||||||
|
writer.println("<pre>INTERNAL_SERVER_ERROR</pre>");
|
||||||
|
writer.println("<p>RequestURI=" + req.getRequestURI() + "</p>");
|
||||||
|
|
||||||
|
writer.println("<pre>");
|
||||||
|
ex.printStackTrace(writer);
|
||||||
|
writer.println("</pre>");
|
||||||
|
|
||||||
|
writer.println("<p><i><small><a href=\"http://jetty.mortbay.org\">Powered by jetty://</a></small></i></p>");
|
||||||
|
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Request base_request = (req instanceof Request) ? (Request)req:HttpConnection.getCurrentConnection().getRequest();
|
||||||
|
base_request.setHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void handleAuthentication(HttpServletResponse resp, JettyHttpExchange jettyHttpExchange, Authenticator auth) throws IOException
|
||||||
|
{
|
||||||
|
Result result = auth.authenticate(jettyHttpExchange);
|
||||||
|
if (result instanceof Authenticator.Failure)
|
||||||
|
{
|
||||||
|
int rc = ((Authenticator.Failure)result).getResponseCode();
|
||||||
|
resp.sendError(rc);
|
||||||
|
}
|
||||||
|
else if (result instanceof Authenticator.Retry)
|
||||||
|
{
|
||||||
|
int rc = ((Authenticator.Retry)result).getResponseCode();
|
||||||
|
resp.sendError(rc);
|
||||||
|
}
|
||||||
|
else if (result instanceof Authenticator.Success)
|
||||||
|
{
|
||||||
|
HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal();
|
||||||
|
jettyHttpExchange.setPrincipal(principal);
|
||||||
|
_httpHandler.handle(jettyHttpExchange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHandler getHttpHandler()
|
||||||
|
{
|
||||||
|
return _httpHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpHandler(HttpHandler handler)
|
||||||
|
{
|
||||||
|
this._httpHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package org.eclipse.jetty.http.spi;
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
//Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//All rights reserved. This program and the accompanying materials
|
||||||
|
//are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
//and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//The Eclipse Public License is available at
|
||||||
|
//http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//The Apache License v2.0 is available at
|
||||||
|
//http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//You may elect to redistribute this code under either of these licenses.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.Authenticator;
|
||||||
|
import com.sun.net.httpserver.Filter;
|
||||||
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty implementation of {@link com.sun.net.httpserver.HttpContext}
|
||||||
|
*/
|
||||||
|
public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
|
||||||
|
{
|
||||||
|
|
||||||
|
private HttpSpiContextHandler _jettyContextHandler;
|
||||||
|
|
||||||
|
private HttpServer _server;
|
||||||
|
|
||||||
|
private Map<String,Object> _attributes = new HashMap<String,Object>();
|
||||||
|
|
||||||
|
private List<Filter> _filters = new ArrayList<Filter>();
|
||||||
|
|
||||||
|
private Authenticator _authenticator;
|
||||||
|
|
||||||
|
|
||||||
|
protected JettyHttpContext(HttpServer server, String path,
|
||||||
|
HttpHandler handler)
|
||||||
|
{
|
||||||
|
this._server = server;
|
||||||
|
_jettyContextHandler = new HttpSpiContextHandler(this, handler);
|
||||||
|
_jettyContextHandler.setContextPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpSpiContextHandler getJettyContextHandler()
|
||||||
|
{
|
||||||
|
return _jettyContextHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHandler getHandler()
|
||||||
|
{
|
||||||
|
return _jettyContextHandler.getHttpHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHandler(HttpHandler h)
|
||||||
|
{
|
||||||
|
_jettyContextHandler.setHttpHandler(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return _jettyContextHandler.getContextPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpServer getServer()
|
||||||
|
{
|
||||||
|
return _server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getAttributes()
|
||||||
|
{
|
||||||
|
return _attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Filter> getFilters()
|
||||||
|
{
|
||||||
|
return _filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authenticator setAuthenticator(Authenticator auth)
|
||||||
|
{
|
||||||
|
Authenticator previous = _authenticator;
|
||||||
|
_authenticator = auth;
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authenticator getAuthenticator()
|
||||||
|
{
|
||||||
|
return _authenticator;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
package org.eclipse.jetty.http.spi;
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
//Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//All rights reserved. This program and the accompanying materials
|
||||||
|
//are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
//and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//The Eclipse Public License is available at
|
||||||
|
//http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//The Apache License v2.0 is available at
|
||||||
|
//http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//You may elect to redistribute this code under either of these licenses.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.Headers;
|
||||||
|
import com.sun.net.httpserver.HttpContext;
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpPrincipal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty implementation of {@link com.sun.net.httpserver.HttpExchange}
|
||||||
|
*/
|
||||||
|
public class JettyHttpExchange extends HttpExchange
|
||||||
|
{
|
||||||
|
|
||||||
|
private HttpContext _httpContext;
|
||||||
|
|
||||||
|
private HttpServletRequest _req;
|
||||||
|
|
||||||
|
private HttpServletResponse _resp;
|
||||||
|
|
||||||
|
private Headers _responseHeaders = new Headers();
|
||||||
|
|
||||||
|
private int _responseCode = 0;
|
||||||
|
|
||||||
|
private InputStream _is;
|
||||||
|
|
||||||
|
private OutputStream _os;
|
||||||
|
|
||||||
|
private HttpPrincipal _httpPrincipal;
|
||||||
|
|
||||||
|
|
||||||
|
public JettyHttpExchange(HttpContext jaxWsContext , HttpServletRequest req,
|
||||||
|
HttpServletResponse resp)
|
||||||
|
{
|
||||||
|
this._httpContext = jaxWsContext;
|
||||||
|
this._req = req;
|
||||||
|
this._resp = resp;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this._is = req.getInputStream();
|
||||||
|
this._os = resp.getOutputStream();
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Headers getRequestHeaders()
|
||||||
|
{
|
||||||
|
Headers headers = new Headers();
|
||||||
|
Enumeration<?> en = _req.getHeaderNames();
|
||||||
|
while (en.hasMoreElements())
|
||||||
|
{
|
||||||
|
String name = (String) en.nextElement();
|
||||||
|
Enumeration<?> en2 = _req.getHeaders(name);
|
||||||
|
while (en2.hasMoreElements())
|
||||||
|
{
|
||||||
|
String value = (String) en2.nextElement();
|
||||||
|
headers.add(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Headers getResponseHeaders()
|
||||||
|
{
|
||||||
|
return _responseHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URI getRequestURI()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String uriAsString = _req.getRequestURI();
|
||||||
|
if (_req.getQueryString() != null)
|
||||||
|
uriAsString += "?" + _req.getQueryString();
|
||||||
|
|
||||||
|
return new URI(uriAsString);
|
||||||
|
}
|
||||||
|
catch (URISyntaxException ex)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRequestMethod()
|
||||||
|
{
|
||||||
|
return _req.getMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpContext getHttpContext()
|
||||||
|
{
|
||||||
|
return _httpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_resp.getOutputStream().close();
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getRequestBody()
|
||||||
|
{
|
||||||
|
return _is;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getResponseBody()
|
||||||
|
{
|
||||||
|
return _os;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendResponseHeaders(int rCode, long responseLength)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this._responseCode = rCode;
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<String>> stringListEntry : _responseHeaders.entrySet())
|
||||||
|
{
|
||||||
|
String name = stringListEntry.getKey();
|
||||||
|
List<String> values = stringListEntry.getValue();
|
||||||
|
|
||||||
|
for (String value : values)
|
||||||
|
{
|
||||||
|
_resp.setHeader(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (responseLength > 0)
|
||||||
|
_resp.setHeader("content-length", "" + responseLength);
|
||||||
|
_resp.setStatus(rCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetSocketAddress getRemoteAddress()
|
||||||
|
{
|
||||||
|
return new InetSocketAddress(_req.getRemoteAddr(), _req.getRemotePort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResponseCode()
|
||||||
|
{
|
||||||
|
return _responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetSocketAddress getLocalAddress()
|
||||||
|
{
|
||||||
|
return new InetSocketAddress(_req.getLocalAddr(), _req.getLocalPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProtocol()
|
||||||
|
{
|
||||||
|
return _req.getProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getAttribute(String name)
|
||||||
|
{
|
||||||
|
return _req.getAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribute(String name, Object value)
|
||||||
|
{
|
||||||
|
_req.setAttribute(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStreams(InputStream i, OutputStream o)
|
||||||
|
{
|
||||||
|
_is = i;
|
||||||
|
_os = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpPrincipal getPrincipal()
|
||||||
|
{
|
||||||
|
return _httpPrincipal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipal(HttpPrincipal principal)
|
||||||
|
{
|
||||||
|
this._httpPrincipal = principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,262 @@
|
||||||
|
package org.eclipse.jetty.http.spi;
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
//Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//All rights reserved. This program and the accompanying materials
|
||||||
|
//are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
//and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//The Eclipse Public License is available at
|
||||||
|
//http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//The Apache License v2.0 is available at
|
||||||
|
//http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//You may elect to redistribute this code under either of these licenses.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpContext;
|
||||||
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
import org.eclipse.jetty.server.Connector;
|
||||||
|
import org.eclipse.jetty.server.Handler;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
|
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
|
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty implementation of {@link com.sun.net.httpserver.HttpServer}.
|
||||||
|
*/
|
||||||
|
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
|
||||||
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(JettyHttpServer.class);
|
||||||
|
|
||||||
|
|
||||||
|
private Server _server;
|
||||||
|
|
||||||
|
private boolean _serverShared;
|
||||||
|
|
||||||
|
private InetSocketAddress _addr;
|
||||||
|
|
||||||
|
private ThreadPoolExecutor _executor;
|
||||||
|
|
||||||
|
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
|
||||||
|
|
||||||
|
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
|
||||||
|
|
||||||
|
|
||||||
|
public JettyHttpServer(Server server, boolean shared)
|
||||||
|
{
|
||||||
|
this._server = server;
|
||||||
|
this._serverShared = shared;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(InetSocketAddress addr, int backlog) throws IOException
|
||||||
|
{
|
||||||
|
// check if there is already a connector listening
|
||||||
|
Connector[] connectors = _server.getConnectors();
|
||||||
|
if (connectors != null)
|
||||||
|
{
|
||||||
|
for (Connector connector : connectors)
|
||||||
|
{
|
||||||
|
if (connector.getPort() == addr.getPort()) {
|
||||||
|
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_serverShared)
|
||||||
|
throw new IOException("jetty server is not bound to port " + addr.getPort());
|
||||||
|
|
||||||
|
this._addr = addr;
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
|
||||||
|
SelectChannelConnector connector = new SelectChannelConnector();
|
||||||
|
connector.setAcceptors(1);
|
||||||
|
connector.setPort(addr.getPort());
|
||||||
|
connector.setHost(addr.getHostName());
|
||||||
|
_server.addConnector(connector);
|
||||||
|
|
||||||
|
_connectors.put(addr.getHostName() + addr.getPort(), connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetSocketAddress getAddress()
|
||||||
|
{
|
||||||
|
return _addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start()
|
||||||
|
{
|
||||||
|
if (_serverShared) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_server.start();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExecutor(Executor executor)
|
||||||
|
{
|
||||||
|
if (executor == null)
|
||||||
|
throw new IllegalArgumentException("missing required 'executor' argument");
|
||||||
|
|
||||||
|
if (!(executor instanceof ThreadPoolExecutor))
|
||||||
|
throw new IllegalArgumentException("only java.util.concurrent.ThreadPoolExecutor instances are allowed, got: " + executor.getClass().getName());
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled()) LOG.debug("using ThreadPoolExecutor for server thread pool");
|
||||||
|
this._executor = (ThreadPoolExecutor) executor;
|
||||||
|
_server.setThreadPool(new ThreadPoolExecutorAdapter(_executor));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Executor getExecutor()
|
||||||
|
{
|
||||||
|
return _executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(int delay)
|
||||||
|
{
|
||||||
|
cleanUpContexts();
|
||||||
|
cleanUpConnectors();
|
||||||
|
|
||||||
|
if (_serverShared) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_server.stop();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanUpContexts()
|
||||||
|
{
|
||||||
|
for (Map.Entry<String, JettyHttpContext> stringJettyHttpContextEntry : _contexts.entrySet())
|
||||||
|
{
|
||||||
|
JettyHttpContext context = stringJettyHttpContextEntry.getValue();
|
||||||
|
_server.removeBean(context.getJettyContextHandler());
|
||||||
|
}
|
||||||
|
_contexts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanUpConnectors()
|
||||||
|
{
|
||||||
|
for (Map.Entry<String, Connector> stringConnectorEntry : _connectors.entrySet())
|
||||||
|
{
|
||||||
|
Connector connector = stringConnectorEntry.getValue();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
connector.stop();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.warn(ex);
|
||||||
|
}
|
||||||
|
_server.removeConnector(connector);
|
||||||
|
}
|
||||||
|
_connectors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpContext createContext(String path, HttpHandler httpHandler)
|
||||||
|
{
|
||||||
|
checkIfContextIsFree(path);
|
||||||
|
|
||||||
|
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
|
||||||
|
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
|
||||||
|
|
||||||
|
ContextHandlerCollection chc = findContextHandlerCollection(_server.getHandlers());
|
||||||
|
if (chc == null)
|
||||||
|
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
|
||||||
|
|
||||||
|
chc.addHandler(jettyContextHandler);
|
||||||
|
_contexts.put(path, context);
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContextHandlerCollection findContextHandlerCollection(Handler[] handlers)
|
||||||
|
{
|
||||||
|
if (handlers == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for (Handler handler : handlers)
|
||||||
|
{
|
||||||
|
if (handler instanceof ContextHandlerCollection)
|
||||||
|
{
|
||||||
|
return (ContextHandlerCollection) handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler instanceof HandlerCollection)
|
||||||
|
{
|
||||||
|
HandlerCollection hc = (HandlerCollection) handler;
|
||||||
|
ContextHandlerCollection chc = findContextHandlerCollection(hc.getHandlers());
|
||||||
|
if (chc != null)
|
||||||
|
return chc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIfContextIsFree(String path)
|
||||||
|
{
|
||||||
|
Handler serverHandler = _server.getHandler();
|
||||||
|
if (serverHandler instanceof ContextHandler)
|
||||||
|
{
|
||||||
|
ContextHandler ctx = (ContextHandler) serverHandler;
|
||||||
|
if (ctx.getContextPath().equals(path))
|
||||||
|
throw new RuntimeException("another context already bound to path " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler[] handlers = _server.getHandlers();
|
||||||
|
if (handlers == null) return;
|
||||||
|
|
||||||
|
for (Handler handler : handlers)
|
||||||
|
{
|
||||||
|
if (handler instanceof ContextHandler) {
|
||||||
|
ContextHandler ctx = (ContextHandler) handler;
|
||||||
|
if (ctx.getContextPath().equals(path))
|
||||||
|
throw new RuntimeException("another context already bound to path " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpContext createContext(String path)
|
||||||
|
{
|
||||||
|
return createContext(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeContext(String path) throws IllegalArgumentException
|
||||||
|
{
|
||||||
|
JettyHttpContext context = _contexts.remove(path);
|
||||||
|
if (context == null) return;
|
||||||
|
_server.removeBean(context.getJettyContextHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeContext(HttpContext context)
|
||||||
|
{
|
||||||
|
removeContext(context.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package org.eclipse.jetty.http.spi;
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
//Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//All rights reserved. This program and the accompanying materials
|
||||||
|
//are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
//and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//The Eclipse Public License is available at
|
||||||
|
//http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//The Apache License v2.0 is available at
|
||||||
|
//http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//You may elect to redistribute this code under either of these licenses.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Handler;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
|
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
|
import com.sun.net.httpserver.HttpsServer;
|
||||||
|
import com.sun.net.httpserver.spi.HttpServerProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty implementation of <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/index.html">Java HTTP Server SPI</a>
|
||||||
|
*/
|
||||||
|
public class JettyHttpServerProvider extends HttpServerProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
private static Server _server;
|
||||||
|
|
||||||
|
public static void setServer(Server server)
|
||||||
|
{
|
||||||
|
_server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpServer createHttpServer(InetSocketAddress addr, int backlog)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
Server server = _server;
|
||||||
|
boolean shared = true;
|
||||||
|
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
server = new Server();
|
||||||
|
|
||||||
|
HandlerCollection handlerCollection = new HandlerCollection();
|
||||||
|
handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()});
|
||||||
|
server.setHandler(handlerCollection);
|
||||||
|
|
||||||
|
shared = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared);
|
||||||
|
jettyHttpServer.bind(addr, backlog);
|
||||||
|
return jettyHttpServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package org.eclipse.jetty.http.spi;
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
//Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//All rights reserved. This program and the accompanying materials
|
||||||
|
//are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
//and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//The Eclipse Public License is available at
|
||||||
|
//http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//The Apache License v2.0 is available at
|
||||||
|
//http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//You may elect to redistribute this code under either of these licenses.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty {@link ThreadPool} that bridges requests to a {@link ThreadPoolExecutor}.
|
||||||
|
*/
|
||||||
|
public class ThreadPoolExecutorAdapter extends AbstractLifeCycle implements ThreadPool
|
||||||
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(ThreadPoolExecutorAdapter.class);
|
||||||
|
|
||||||
|
|
||||||
|
private ThreadPoolExecutor executor;
|
||||||
|
|
||||||
|
public ThreadPoolExecutorAdapter(ThreadPoolExecutor executor)
|
||||||
|
{
|
||||||
|
this.executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dispatch(Runnable job)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
executor.execute(job);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(RejectedExecutionException e)
|
||||||
|
{
|
||||||
|
LOG.warn(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIdleThreads()
|
||||||
|
{
|
||||||
|
return executor.getPoolSize()-executor.getActiveCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getThreads()
|
||||||
|
{
|
||||||
|
return executor.getPoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLowOnThreads()
|
||||||
|
{
|
||||||
|
return executor.getActiveCount()>=executor.getMaximumPoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void join() throws InterruptedException
|
||||||
|
{
|
||||||
|
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isFailed()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning()
|
||||||
|
{
|
||||||
|
return !executor.isTerminated() && !executor.isTerminating();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarted()
|
||||||
|
{
|
||||||
|
return !executor.isTerminated() && !executor.isTerminating();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarting()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStopped()
|
||||||
|
{
|
||||||
|
return executor.isTerminated();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStopping()
|
||||||
|
{
|
||||||
|
return executor.isTerminating();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doStart() throws Exception
|
||||||
|
{
|
||||||
|
if (executor.isTerminated() || executor.isTerminating() || executor.isShutdown())
|
||||||
|
throw new IllegalStateException("Cannot restart");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doStop() throws Exception
|
||||||
|
{
|
||||||
|
executor.shutdown();
|
||||||
|
if (!executor.awaitTermination(60, TimeUnit.SECONDS))
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
org.eclipse.jetty.http.spi.JettyHttpServerProvider
|
|
@ -242,7 +242,10 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
||||||
if (_closing)
|
if (_closing)
|
||||||
{
|
{
|
||||||
if (outBuf!=null && outBuf.hasContent())
|
if (outBuf!=null && outBuf.hasContent())
|
||||||
throw new IOException("Write while closing");
|
{
|
||||||
|
LOG.debug("Write while closing");
|
||||||
|
outBuf.clear();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +320,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
||||||
|
|
||||||
// Need more data to be unwrapped so try another call to unwrap
|
// Need more data to be unwrapped so try another call to unwrap
|
||||||
progress|=unwrap(inBBuf);
|
progress|=unwrap(inBBuf);
|
||||||
if (_closing)
|
if (_closing && inBBuf.hasRemaining())
|
||||||
inBBuf.clear();
|
inBBuf.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -338,15 +341,16 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
if (_closing)
|
// For safety we always force a close calling super
|
||||||
return;
|
|
||||||
|
|
||||||
_closing=true;
|
|
||||||
LOG.debug("{} close",_session);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_engine.closeOutbound();
|
if (!_closing)
|
||||||
process(null,null);
|
{
|
||||||
|
_closing=true;
|
||||||
|
LOG.debug("{} close",_session);
|
||||||
|
_engine.closeOutbound();
|
||||||
|
process(null,null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
@ -642,7 +646,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
||||||
catch(SSLException e)
|
catch(SSLException e)
|
||||||
{
|
{
|
||||||
LOG.warn(getRemoteAddr()+":"+getRemotePort()+" ",e);
|
LOG.warn(getRemoteAddr()+":"+getRemotePort()+" ",e);
|
||||||
super.close();
|
if (getChannel().isOpen())
|
||||||
|
getChannel().close();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -142,13 +142,13 @@ public class AsyncHttpConnection extends HttpConnection
|
||||||
LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NO_PROGRESS_CLOSE>0 && _total_no_progress>NO_PROGRESS_CLOSE)
|
if (NO_PROGRESS_CLOSE>0 && _total_no_progress==NO_PROGRESS_CLOSE)
|
||||||
{
|
{
|
||||||
LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
||||||
_endp.close();
|
|
||||||
if (_endp instanceof SelectChannelEndPoint)
|
if (_endp instanceof SelectChannelEndPoint)
|
||||||
{
|
{
|
||||||
System.err.println(((SelectChannelEndPoint)_endp).getSelectManager().dump());
|
System.err.println(((SelectChannelEndPoint)_endp).getSelectManager().dump());
|
||||||
|
((SelectChannelEndPoint)_endp).getChannel().close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,13 +34,30 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
* Usage:
|
* Usage:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* Server server = new Server(8080);
|
Server server = new Server(8080);
|
||||||
* HandlerList handlers = new HandlerList();
|
HandlerList handlers = new HandlerList();
|
||||||
* handlers.setHandlers(new Handler[]
|
handlers.setHandlers(new Handler[]
|
||||||
* { someOtherHandler, new ShutdownHandler(server,"secret password") });
|
{ someOtherHandler, new ShutdownHandler(server,"secret password") });
|
||||||
* server.setHandler(handlers);
|
server.setHandler(handlers);
|
||||||
* server.start();
|
server.start();
|
||||||
* </pre>
|
</pre>
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
public static void attemptShutdown(int port, String shutdownCookie) {
|
||||||
|
try {
|
||||||
|
URL url = new URL("http://localhost:" + port + "/shutdown?cookie=" + shutdownCookie);
|
||||||
|
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
connection.getResponseCode();
|
||||||
|
logger.info("Shutting down " + url + ": " + connection.getResponseMessage());
|
||||||
|
} catch (SocketException e) {
|
||||||
|
logger.debug("Not running");
|
||||||
|
// Okay - the server is not running
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
*/
|
*/
|
||||||
public class ShutdownHandler extends AbstractHandler
|
public class ShutdownHandler extends AbstractHandler
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,64 +13,74 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.log;
|
package org.eclipse.jetty.util.log;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.security.AccessControlException;
|
import java.security.AccessControlException;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.DateCache;
|
import org.eclipse.jetty.util.DateCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StdErr Logging. This implementation of the Logging facade sends all logs to
|
* StdErr Logging. This implementation of the Logging facade sends all logs to StdErr with minimal formatting.
|
||||||
* StdErr with minimal formatting.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the system property "org.eclipse.jetty.util.log.DEBUG" is set, then debug
|
* If the system property "org.eclipse.jetty.LEVEL" is set to one of the following (ALL, DEBUG, INFO, WARN), then set
|
||||||
* logs are printed if stderr is being used. For named debuggers, the system
|
* the eclipse jetty root level logger level to that specified level. (Default level is INFO)
|
||||||
* property name+".DEBUG" is checked. If it is not not set, then
|
|
||||||
* "org.eclipse.jetty.util.log.DEBUG" is used as the default.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the system property "org.eclipse.jetty.util.log.SOURCE" is set, then the
|
* If the system property "org.eclipse.jetty.util.log.SOURCE" is set, then the source method/file of a log is logged.
|
||||||
* source method/file of a log is logged. For named debuggers, the system
|
* For named debuggers, the system property name+".SOURCE" is checked. If it is not not set, then
|
||||||
* property name+".SOURCE" is checked. If it is not not set, then
|
|
||||||
* "org.eclipse.jetty.util.log.SOURCE" is used as the default.
|
* "org.eclipse.jetty.util.log.SOURCE" is used as the default.
|
||||||
* <p>
|
* <p>
|
||||||
* If the system property "org.eclipse.jetty.util.log.LONG" is set, then the
|
* If the system property "org.eclipse.jetty.util.log.LONG" is set, then the full, unabbreviated name of the logger is
|
||||||
* full, unabbreviated name of the logger is used for logging.
|
* used for logging. For named debuggers, the system property name+".LONG" is checked. If it is not not set, then
|
||||||
* For named debuggers, the system property name+".LONG" is checked.
|
* "org.eclipse.jetty.util.log.LONG" is used as the default.
|
||||||
* If it is not not set, then "org.eclipse.jetty.util.log.LONG" is used as the default.
|
|
||||||
*/
|
*/
|
||||||
public class StdErrLog implements Logger
|
public class StdErrLog implements Logger
|
||||||
{
|
{
|
||||||
private static DateCache _dateCache;
|
private static DateCache _dateCache;
|
||||||
|
|
||||||
private final static boolean __debug = Boolean.parseBoolean(
|
private final static boolean __source = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.SOURCE",
|
||||||
System.getProperty("org.eclipse.jetty.util.log.DEBUG",
|
System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
|
||||||
System.getProperty("org.eclipse.jetty.util.log.stderr.DEBUG", "false")));
|
private final static boolean __long = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
|
||||||
private final static boolean __source = Boolean.parseBoolean(
|
|
||||||
System.getProperty("org.eclipse.jetty.util.log.SOURCE",
|
private final static ConcurrentMap<String, StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
|
||||||
System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE", "false")));
|
|
||||||
private final static boolean __long = Boolean.parseBoolean(
|
|
||||||
System.getProperty("org.eclipse.jetty.util.log.stderr.LONG", "false"));
|
|
||||||
|
|
||||||
private final static ConcurrentMap<String,StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
|
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
String deprecatedProperites[] =
|
||||||
|
{ "DEBUG", "org.eclipse.jetty.util.log.DEBUG", "org.eclipse.jetty.util.log.stderr.DEBUG" };
|
||||||
|
|
||||||
|
// Toss a message to users about deprecated system properties
|
||||||
|
for (String deprecatedProp : deprecatedProperites)
|
||||||
|
{
|
||||||
|
if (System.getProperty(deprecatedProp) != null)
|
||||||
|
{
|
||||||
|
System.err.printf("System Property [%s] has been deprecated! (Use org.eclipse.jetty.LEVEL=DEBUG instead)%n",deprecatedProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
|
_dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
|
||||||
}
|
}
|
||||||
catch (Exception x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
x.printStackTrace();
|
x.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean _debug = __debug;
|
public static final int LEVEL_ALL = 0;
|
||||||
|
public static final int LEVEL_DEBUG = 1;
|
||||||
|
public static final int LEVEL_INFO = 2;
|
||||||
|
public static final int LEVEL_WARN = 3;
|
||||||
|
|
||||||
|
private int _level = LEVEL_INFO;
|
||||||
|
private PrintStream _stderr = System.err;
|
||||||
private boolean _source = __source;
|
private boolean _source = __source;
|
||||||
// Print the long form names, otherwise use abbreviated
|
// Print the long form names, otherwise use abbreviated
|
||||||
private boolean _printLongNames = __long;
|
private boolean _printLongNames = __long;
|
||||||
// The full log name, as provided by the system.
|
// The full log name, as provided by the system.
|
||||||
private final String _name;
|
private final String _name;
|
||||||
// The abbreviated log name (used by default, unless _long is specified)
|
// The abbreviated log name (used by default, unless _long is specified)
|
||||||
private final String _abbrevname;
|
private final String _abbrevname;
|
||||||
private boolean _hideStacks = false;
|
private boolean _hideStacks = false;
|
||||||
|
@ -82,31 +92,81 @@ public class StdErrLog implements Logger
|
||||||
|
|
||||||
public StdErrLog(String name)
|
public StdErrLog(String name)
|
||||||
{
|
{
|
||||||
this._name = name == null ? "" : name;
|
this._name = name == null?"":name;
|
||||||
this._abbrevname = condensePackageString(this._name);
|
this._abbrevname = condensePackageString(this._name);
|
||||||
|
this._level = getLoggingLevel(System.getProperties(),this._name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_debug = Boolean.parseBoolean(System.getProperty(_name + ".DEBUG", Boolean.toString(_debug)));
|
_source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE",Boolean.toString(_source)));
|
||||||
}
|
|
||||||
catch (AccessControlException ace)
|
|
||||||
{
|
|
||||||
_debug = __debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE", Boolean.toString(_source)));
|
|
||||||
}
|
}
|
||||||
catch (AccessControlException ace)
|
catch (AccessControlException ace)
|
||||||
{
|
{
|
||||||
_source = __source;
|
_source = __source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Logging Level for the provided log name. Using the FQCN first, then each package segment from longest to
|
||||||
|
* shortest.
|
||||||
|
*
|
||||||
|
* @param props
|
||||||
|
* the properties to check
|
||||||
|
* @param name
|
||||||
|
* the name to get log for
|
||||||
|
* @return the logging level
|
||||||
|
*/
|
||||||
|
public static int getLoggingLevel(Properties props, final String name)
|
||||||
|
{
|
||||||
|
// Calculate the level this named logger should operate under.
|
||||||
|
// Checking with FQCN first, then each package segment from longest to shortest.
|
||||||
|
String nameSegment = name;
|
||||||
|
|
||||||
|
while ((nameSegment != null) && (nameSegment.length() > 0))
|
||||||
|
{
|
||||||
|
String levelStr = props.getProperty(nameSegment + ".LEVEL");
|
||||||
|
// System.err.printf("[StdErrLog.CONFIG] Checking for property [%s.LEVEL] = %s%n",nameSegment,levelStr);
|
||||||
|
if (levelStr == null)
|
||||||
|
{
|
||||||
|
// Trim and try again.
|
||||||
|
int idx = nameSegment.lastIndexOf('.');
|
||||||
|
if (idx >= 0)
|
||||||
|
{
|
||||||
|
nameSegment = nameSegment.substring(0,idx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nameSegment = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ("ALL".equalsIgnoreCase(levelStr.trim()))
|
||||||
|
{
|
||||||
|
return LEVEL_ALL;
|
||||||
|
}
|
||||||
|
else if ("DEBUG".equalsIgnoreCase(levelStr.trim()))
|
||||||
|
{
|
||||||
|
return LEVEL_DEBUG;
|
||||||
|
}
|
||||||
|
else if ("INFO".equalsIgnoreCase(levelStr.trim()))
|
||||||
|
{
|
||||||
|
return LEVEL_INFO;
|
||||||
|
}
|
||||||
|
else if ("WARN".equalsIgnoreCase(levelStr.trim()))
|
||||||
|
{
|
||||||
|
return LEVEL_WARN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Logging Level
|
||||||
|
return LEVEL_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Condenses a classname by stripping down the package name to just the first character of each package name
|
* Condenses a classname by stripping down the package name to just the first character of each package name
|
||||||
* segment.
|
* segment.Configured
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
|
@ -139,7 +199,7 @@ public class StdErrLog implements Logger
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrintLongNames(boolean printLongNames)
|
public void setPrintLongNames(boolean printLongNames)
|
||||||
{
|
{
|
||||||
this._printLongNames = printLongNames;
|
this._printLongNames = printLongNames;
|
||||||
|
@ -161,7 +221,9 @@ public class StdErrLog implements Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Is the source of a log, logged
|
/**
|
||||||
|
* Is the source of a log, logged
|
||||||
|
*
|
||||||
* @return true if the class, method, file and line number of a log is logged.
|
* @return true if the class, method, file and line number of a log is logged.
|
||||||
*/
|
*/
|
||||||
public boolean isSource()
|
public boolean isSource()
|
||||||
|
@ -170,8 +232,11 @@ public class StdErrLog implements Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Set if a log source is logged.
|
/**
|
||||||
* @param source true if the class, method, file and line number of a log is logged.
|
* Set if a log source is logged.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* true if the class, method, file and line number of a log is logged.
|
||||||
*/
|
*/
|
||||||
public void setSource(boolean source)
|
public void setSource(boolean source)
|
||||||
{
|
{
|
||||||
|
@ -180,90 +245,143 @@ public class StdErrLog implements Logger
|
||||||
|
|
||||||
public void warn(String msg, Object... args)
|
public void warn(String msg, Object... args)
|
||||||
{
|
{
|
||||||
StringBuilder buffer = new StringBuilder(64);
|
if (_level <= LEVEL_WARN)
|
||||||
format(buffer, ":WARN:", msg, args);
|
{
|
||||||
System.err.println(buffer);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
|
format(buffer,":WARN:",msg,args);
|
||||||
|
_stderr.println(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void warn(Throwable thrown)
|
public void warn(Throwable thrown)
|
||||||
{
|
{
|
||||||
warn("", thrown);
|
warn("",thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void warn(String msg, Throwable thrown)
|
public void warn(String msg, Throwable thrown)
|
||||||
{
|
{
|
||||||
StringBuilder buffer = new StringBuilder(64);
|
if (_level <= LEVEL_WARN)
|
||||||
format(buffer, ":WARN:", msg, thrown);
|
{
|
||||||
System.err.println(buffer);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
|
format(buffer,":WARN:",msg,thrown);
|
||||||
|
_stderr.println(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void info(String msg, Object... args)
|
public void info(String msg, Object... args)
|
||||||
{
|
{
|
||||||
StringBuilder buffer = new StringBuilder(64);
|
if (_level <= LEVEL_INFO)
|
||||||
format(buffer, ":INFO:", msg, args);
|
{
|
||||||
System.err.println(buffer);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
|
format(buffer,":INFO:",msg,args);
|
||||||
|
_stderr.println(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void info(Throwable thrown)
|
public void info(Throwable thrown)
|
||||||
{
|
{
|
||||||
info("", thrown);
|
info("",thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void info(String msg, Throwable thrown)
|
public void info(String msg, Throwable thrown)
|
||||||
{
|
{
|
||||||
StringBuilder buffer = new StringBuilder(64);
|
if (_level <= LEVEL_INFO)
|
||||||
format(buffer, ":INFO:", msg, thrown);
|
{
|
||||||
System.err.println(buffer);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
|
format(buffer,":INFO:",msg,thrown);
|
||||||
|
_stderr.println(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDebugEnabled()
|
public boolean isDebugEnabled()
|
||||||
{
|
{
|
||||||
return _debug;
|
return (_level >= LEVEL_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link #setLevel(int)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setDebugEnabled(boolean enabled)
|
public void setDebugEnabled(boolean enabled)
|
||||||
{
|
{
|
||||||
_debug = enabled;
|
if (enabled)
|
||||||
|
{
|
||||||
|
_level = LEVEL_DEBUG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_level = LEVEL_INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel()
|
||||||
|
{
|
||||||
|
return _level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the level for this logger.
|
||||||
|
* <p>
|
||||||
|
* Available values ({@link StdErrLog#LEVEL_ALL}, {@link StdErrLog#LEVEL_DEBUG}, {@link StdErrLog#LEVEL_INFO},
|
||||||
|
* {@link StdErrLog#LEVEL_WARN})
|
||||||
|
*
|
||||||
|
* @param level
|
||||||
|
* the level to set the logger to
|
||||||
|
*/
|
||||||
|
public void setLevel(int level)
|
||||||
|
{
|
||||||
|
this._level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStdErrStream(PrintStream stream)
|
||||||
|
{
|
||||||
|
this._stderr = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void debug(String msg, Object... args)
|
public void debug(String msg, Object... args)
|
||||||
{
|
{
|
||||||
if (!_debug)
|
if (_level <= LEVEL_DEBUG)
|
||||||
return;
|
{
|
||||||
StringBuilder buffer = new StringBuilder(64);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
format(buffer, ":DBUG:", msg, args);
|
format(buffer,":DBUG:",msg,args);
|
||||||
System.err.println(buffer);
|
_stderr.println(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void debug(Throwable thrown)
|
public void debug(Throwable thrown)
|
||||||
{
|
{
|
||||||
debug("", thrown);
|
debug("",thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void debug(String msg, Throwable thrown)
|
public void debug(String msg, Throwable thrown)
|
||||||
{
|
{
|
||||||
if (!_debug)
|
if (_level <= LEVEL_DEBUG)
|
||||||
return;
|
{
|
||||||
StringBuilder buffer = new StringBuilder(64);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
format(buffer, ":DBUG:", msg, thrown);
|
format(buffer,":DBUG:",msg,thrown);
|
||||||
System.err.println(buffer);
|
_stderr.println(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void format(StringBuilder buffer, String level, String msg, Object... args)
|
private void format(StringBuilder buffer, String level, String msg, Object... args)
|
||||||
{
|
{
|
||||||
String d = _dateCache.now();
|
String d = _dateCache.now();
|
||||||
int ms = _dateCache.lastMs();
|
int ms = _dateCache.lastMs();
|
||||||
tag(buffer, d, ms, level);
|
tag(buffer,d,ms,level);
|
||||||
format(buffer, msg, args);
|
format(buffer,msg,args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
|
private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
|
||||||
{
|
{
|
||||||
format(buffer, level, msg);
|
format(buffer,level,msg);
|
||||||
if (isHideStacks())
|
if (isHideStacks())
|
||||||
format(buffer, String.valueOf(thrown));
|
{
|
||||||
|
format(buffer,String.valueOf(thrown));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
format(buffer, thrown);
|
{
|
||||||
|
format(buffer,thrown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tag(StringBuilder buffer, String d, int ms, String tag)
|
private void tag(StringBuilder buffer, String d, int ms, String tag)
|
||||||
|
@ -271,36 +389,52 @@ public class StdErrLog implements Logger
|
||||||
buffer.setLength(0);
|
buffer.setLength(0);
|
||||||
buffer.append(d);
|
buffer.append(d);
|
||||||
if (ms > 99)
|
if (ms > 99)
|
||||||
|
{
|
||||||
buffer.append('.');
|
buffer.append('.');
|
||||||
|
}
|
||||||
else if (ms > 9)
|
else if (ms > 9)
|
||||||
|
{
|
||||||
buffer.append(".0");
|
buffer.append(".0");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
buffer.append(".00");
|
buffer.append(".00");
|
||||||
|
}
|
||||||
buffer.append(ms).append(tag);
|
buffer.append(ms).append(tag);
|
||||||
if(_printLongNames) {
|
if (_printLongNames)
|
||||||
|
{
|
||||||
buffer.append(_name);
|
buffer.append(_name);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
buffer.append(_abbrevname);
|
buffer.append(_abbrevname);
|
||||||
}
|
}
|
||||||
buffer.append(':');
|
buffer.append(':');
|
||||||
if (_source)
|
if (_source)
|
||||||
{
|
{
|
||||||
Throwable source = new Throwable();
|
Throwable source = new Throwable();
|
||||||
StackTraceElement[] frames = source.getStackTrace();
|
StackTraceElement[] frames = source.getStackTrace();
|
||||||
for (int i=0;i<frames.length;i++)
|
for (int i = 0; i < frames.length; i++)
|
||||||
{
|
{
|
||||||
final StackTraceElement frame = frames[i];
|
final StackTraceElement frame = frames[i];
|
||||||
String clazz = frame.getClassName();
|
String clazz = frame.getClassName();
|
||||||
if (clazz.equals(StdErrLog.class.getName())|| clazz.equals(Log.class.getName()))
|
if (clazz.equals(StdErrLog.class.getName()) || clazz.equals(Log.class.getName()))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
if (!_printLongNames && clazz.startsWith("org.eclipse.jetty.")) {
|
}
|
||||||
|
if (!_printLongNames && clazz.startsWith("org.eclipse.jetty."))
|
||||||
|
{
|
||||||
buffer.append(condensePackageString(clazz));
|
buffer.append(condensePackageString(clazz));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
buffer.append(clazz);
|
buffer.append(clazz);
|
||||||
}
|
}
|
||||||
buffer.append('#').append(frame.getMethodName());
|
buffer.append('#').append(frame.getMethodName());
|
||||||
if (frame.getFileName()!=null)
|
if (frame.getFileName() != null)
|
||||||
|
{
|
||||||
buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
|
buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
|
||||||
|
}
|
||||||
buffer.append(':');
|
buffer.append(':');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -309,32 +443,34 @@ public class StdErrLog implements Logger
|
||||||
|
|
||||||
private void format(StringBuilder builder, String msg, Object... args)
|
private void format(StringBuilder builder, String msg, Object... args)
|
||||||
{
|
{
|
||||||
if (msg==null)
|
if (msg == null)
|
||||||
{
|
{
|
||||||
msg="";
|
msg = "";
|
||||||
for (Object o : args)
|
for (int i = 0; i < args.length; i++)
|
||||||
msg+="{} ";
|
{
|
||||||
|
msg += "{} ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String braces = "{}";
|
String braces = "{}";
|
||||||
int start = 0;
|
int start = 0;
|
||||||
for (Object arg : args)
|
for (Object arg : args)
|
||||||
{
|
{
|
||||||
int bracesIndex = msg.indexOf(braces, start);
|
int bracesIndex = msg.indexOf(braces,start);
|
||||||
if (bracesIndex < 0)
|
if (bracesIndex < 0)
|
||||||
{
|
{
|
||||||
escape(builder, msg.substring(start));
|
escape(builder,msg.substring(start));
|
||||||
builder.append(" ");
|
builder.append(" ");
|
||||||
builder.append(arg);
|
builder.append(arg);
|
||||||
start = msg.length();
|
start = msg.length();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
escape(builder, msg.substring(start, bracesIndex));
|
escape(builder,msg.substring(start,bracesIndex));
|
||||||
builder.append(String.valueOf(arg));
|
builder.append(String.valueOf(arg));
|
||||||
start = bracesIndex + braces.length();
|
start = bracesIndex + braces.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
escape(builder, msg.substring(start));
|
escape(builder,msg.substring(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void escape(StringBuilder builder, String string)
|
private void escape(StringBuilder builder, String string)
|
||||||
|
@ -345,14 +481,22 @@ public class StdErrLog implements Logger
|
||||||
if (Character.isISOControl(c))
|
if (Character.isISOControl(c))
|
||||||
{
|
{
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
|
{
|
||||||
builder.append('|');
|
builder.append('|');
|
||||||
|
}
|
||||||
else if (c == '\r')
|
else if (c == '\r')
|
||||||
|
{
|
||||||
builder.append('<');
|
builder.append('<');
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
builder.append('?');
|
builder.append('?');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
builder.append(c);
|
builder.append(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,16 +509,16 @@ public class StdErrLog implements Logger
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer.append('\n');
|
buffer.append('\n');
|
||||||
format(buffer, thrown.toString());
|
format(buffer,thrown.toString());
|
||||||
StackTraceElement[] elements = thrown.getStackTrace();
|
StackTraceElement[] elements = thrown.getStackTrace();
|
||||||
for (int i = 0; elements != null && i < elements.length; i++)
|
for (int i = 0; elements != null && i < elements.length; i++)
|
||||||
{
|
{
|
||||||
buffer.append("\n\tat ");
|
buffer.append("\n\tat ");
|
||||||
format(buffer, elements[i].toString());
|
format(buffer,elements[i].toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Throwable cause = thrown.getCause();
|
Throwable cause = thrown.getCause();
|
||||||
if (cause!=null && cause!=thrown)
|
if (cause != null && cause != thrown)
|
||||||
{
|
{
|
||||||
buffer.append("\nCaused by: ");
|
buffer.append("\nCaused by: ");
|
||||||
format(buffer,cause);
|
format(buffer,cause);
|
||||||
|
@ -384,42 +528,66 @@ public class StdErrLog implements Logger
|
||||||
|
|
||||||
public Logger getLogger(String name)
|
public Logger getLogger(String name)
|
||||||
{
|
{
|
||||||
String fullname=_name == null || _name.length() == 0?name:_name + "." + name;
|
String fullname = _name == null || _name.length() == 0?name:_name + "." + name;
|
||||||
|
|
||||||
if ((name == null && this._name == null) || fullname.equals(_name))
|
if ((name == null && this._name == null) || fullname.equals(_name))
|
||||||
return this;
|
|
||||||
|
|
||||||
StdErrLog logger = __loggers.get(name);
|
|
||||||
if (logger==null)
|
|
||||||
{
|
{
|
||||||
StdErrLog sel=new StdErrLog(fullname);
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StdErrLog logger = __loggers.get(name);
|
||||||
|
if (logger == null)
|
||||||
|
{
|
||||||
|
StdErrLog sel = new StdErrLog(fullname);
|
||||||
// Preserve configuration for new loggers configuration
|
// Preserve configuration for new loggers configuration
|
||||||
sel.setPrintLongNames(_printLongNames);
|
sel.setPrintLongNames(_printLongNames);
|
||||||
sel.setDebugEnabled(_debug);
|
sel.setLevel(_level);
|
||||||
sel.setSource(_source);
|
sel.setSource(_source);
|
||||||
logger=__loggers.putIfAbsent(fullname,sel);
|
logger = __loggers.putIfAbsent(fullname,sel);
|
||||||
if (logger==null)
|
if (logger == null)
|
||||||
logger=sel;
|
{
|
||||||
|
logger = sel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "StdErrLog:" + _name + ":DEBUG=" + _debug;
|
StringBuilder s = new StringBuilder();
|
||||||
|
s.append("StdErrLog:");
|
||||||
|
s.append(_name);
|
||||||
|
s.append(":LEVEL=");
|
||||||
|
switch (_level)
|
||||||
|
{
|
||||||
|
case LEVEL_ALL:
|
||||||
|
s.append("ALL");
|
||||||
|
break;
|
||||||
|
case LEVEL_DEBUG:
|
||||||
|
s.append("DEBUG");
|
||||||
|
break;
|
||||||
|
case LEVEL_INFO:
|
||||||
|
s.append("INFO");
|
||||||
|
break;
|
||||||
|
case LEVEL_WARN:
|
||||||
|
s.append("WARN");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s.append("?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return s.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ignore(Throwable ignored)
|
public void ignore(Throwable ignored)
|
||||||
{
|
{
|
||||||
if (Log.isIgnored())
|
if (_level <= LEVEL_ALL)
|
||||||
{
|
{
|
||||||
warn(Log.IGNORED, ignored);
|
StringBuilder buffer = new StringBuilder(64);
|
||||||
|
format(buffer,":IGNORED:","",ignored);
|
||||||
|
_stderr.println(buffer);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
debug("Ignored {}",ignored.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,12 +101,13 @@ public class LogTest
|
||||||
logContains("INFO:oejul.LogTest:testing");
|
logContains("INFO:oejul.LogTest:testing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testStdErrLogDebug()
|
public void testStdErrLogDebug()
|
||||||
{
|
{
|
||||||
StdErrLog log = new StdErrLog("xxx");
|
StdErrLog log = new StdErrLog("xxx");
|
||||||
|
|
||||||
log.setDebugEnabled(true);
|
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||||
log.debug("testing {} {}","test","debug");
|
log.debug("testing {} {}","test","debug");
|
||||||
logContains("DBUG:xxx:testing test debug");
|
logContains("DBUG:xxx:testing test debug");
|
||||||
|
|
||||||
|
@ -116,9 +117,18 @@ public class LogTest
|
||||||
log.warn("testing {} {}","test","warn");
|
log.warn("testing {} {}","test","warn");
|
||||||
logContains("WARN:xxx:testing test warn");
|
logContains("WARN:xxx:testing test warn");
|
||||||
|
|
||||||
log.setDebugEnabled(false);
|
log.setLevel(StdErrLog.LEVEL_INFO);
|
||||||
log.debug("YOU SHOULD NOT SEE THIS!",null,null);
|
log.debug("YOU SHOULD NOT SEE THIS!",null,null);
|
||||||
logNotContains("YOU SHOULD NOT SEE THIS!");
|
logNotContains("YOU SHOULD NOT SEE THIS!");
|
||||||
|
|
||||||
|
// Test for backward compat with old (now deprecated) method
|
||||||
|
log.setDebugEnabled(true);
|
||||||
|
log.debug("testing {} {}","test","debug-deprecated");
|
||||||
|
logContains("DBUG:xxx:testing test debug-deprecated");
|
||||||
|
|
||||||
|
log.setDebugEnabled(false);
|
||||||
|
log.debug("testing {} {}","test","debug-deprecated-false");
|
||||||
|
logNotContains("DBUG:xxx:testing test debug-depdeprecated-false");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -134,7 +144,6 @@ public class LogTest
|
||||||
|
|
||||||
next.info("testing {} {}","next","info");
|
next.info("testing {} {}","next","info");
|
||||||
logContains(":test.next:testing next info");
|
logContains(":test.next:testing next info");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -164,6 +173,5 @@ public class LogTest
|
||||||
logContains("Message with ? escape");
|
logContains("Message with ? escape");
|
||||||
log.info(th.toString());
|
log.info(th.toString());
|
||||||
logContains("Message with ? escape");
|
logContains("Message with ? escape");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,70 +13,270 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.log;
|
package org.eclipse.jetty.util.log;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author mgorovoy
|
* Tests for StdErrLog
|
||||||
* */
|
*/
|
||||||
public class StdErrLogTest extends TestCase
|
public class StdErrLogTest
|
||||||
{
|
{
|
||||||
public void testNullValues()
|
/**
|
||||||
|
* Test to make sure that using a Null parameter on parameterized messages does not result in a NPE
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParameterizedMessage_NullValues() throws NullPointerException
|
||||||
{
|
{
|
||||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||||
log.setDebugEnabled(true);
|
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||||
log.setHideStacks(true);
|
log.setHideStacks(true);
|
||||||
|
|
||||||
try {
|
log.info("Testing info(msg,null,null) - {} {}","arg0","arg1");
|
||||||
log.info("Testing info(msg,null,null) - {} {}","arg0","arg1");
|
log.info("Testing info(msg,null,null) - {} {}",null,null);
|
||||||
log.info("Testing info(msg,null,null) - {} {}",null,null);
|
log.info("Testing info(msg,null,null) - {}",null,null);
|
||||||
log.info("Testing info(msg,null,null) - {}",null,null);
|
log.info("Testing info(msg,null,null)",null,null);
|
||||||
log.info("Testing info(msg,null,null)",null,null);
|
log.info(null,"Testing","info(null,arg0,arg1)");
|
||||||
log.info(null,"Testing","info(null,arg0,arg1)");
|
log.info(null,null,null);
|
||||||
log.info(null,null,null);
|
|
||||||
|
|
||||||
log.debug("Testing debug(msg,null,null) - {} {}","arg0","arg1");
|
log.debug("Testing debug(msg,null,null) - {} {}","arg0","arg1");
|
||||||
log.debug("Testing debug(msg,null,null) - {} {}",null,null);
|
log.debug("Testing debug(msg,null,null) - {} {}",null,null);
|
||||||
log.debug("Testing debug(msg,null,null) - {}",null,null);
|
log.debug("Testing debug(msg,null,null) - {}",null,null);
|
||||||
log.debug("Testing debug(msg,null,null)",null,null);
|
log.debug("Testing debug(msg,null,null)",null,null);
|
||||||
log.debug(null,"Testing","debug(null,arg0,arg1)");
|
log.debug(null,"Testing","debug(null,arg0,arg1)");
|
||||||
log.debug(null,null,null);
|
log.debug(null,null,null);
|
||||||
|
|
||||||
log.debug("Testing debug(msg,null)");
|
log.debug("Testing debug(msg,null)");
|
||||||
log.debug(null,new Throwable("Testing debug(null,thrw)").fillInStackTrace());
|
log.debug(null,new Throwable("Testing debug(null,thrw)").fillInStackTrace());
|
||||||
|
|
||||||
log.warn("Testing warn(msg,null,null) - {} {}","arg0","arg1");
|
log.warn("Testing warn(msg,null,null) - {} {}","arg0","arg1");
|
||||||
log.warn("Testing warn(msg,null,null) - {} {}",null,null);
|
log.warn("Testing warn(msg,null,null) - {} {}",null,null);
|
||||||
log.warn("Testing warn(msg,null,null) - {}",null,null);
|
log.warn("Testing warn(msg,null,null) - {}",null,null);
|
||||||
log.warn("Testing warn(msg,null,null)",null,null);
|
log.warn("Testing warn(msg,null,null)",null,null);
|
||||||
log.warn(null,"Testing","warn(msg,arg0,arg1)");
|
log.warn(null,"Testing","warn(msg,arg0,arg1)");
|
||||||
log.warn(null,null,null);
|
log.warn(null,null,null);
|
||||||
|
|
||||||
log.warn("Testing warn(msg,null)");
|
log.warn("Testing warn(msg,null)");
|
||||||
log.warn(null,new Throwable("Testing warn(msg,thrw)").fillInStackTrace());
|
log.warn(null,new Throwable("Testing warn(msg,thrw)").fillInStackTrace());
|
||||||
}
|
|
||||||
catch (NullPointerException npe)
|
|
||||||
{
|
|
||||||
System.err.println(npe);
|
|
||||||
npe.printStackTrace();
|
|
||||||
assertTrue("NullPointerException in StdErrLog.", false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIgnores()
|
@Test
|
||||||
|
public void testGetLoggingLevel_Default()
|
||||||
|
{
|
||||||
|
Properties props = new Properties();
|
||||||
|
|
||||||
|
// Default Levels
|
||||||
|
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||||
|
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||||
|
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||||
|
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,StdErrLogTest.class.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLoggingLevel_FQCN()
|
||||||
|
{
|
||||||
|
String name = StdErrLogTest.class.getName();
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty(name + ".LEVEL","ALL");
|
||||||
|
|
||||||
|
// Default Levels
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||||
|
|
||||||
|
// Specified Level
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_ALL,StdErrLog.getLoggingLevel(props,name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLoggingLevel_UtilLevel()
|
||||||
|
{
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty("org.eclipse.jetty.util.LEVEL","DEBUG");
|
||||||
|
|
||||||
|
// Default Levels
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.server.BogusObject"));
|
||||||
|
|
||||||
|
// Configured Level
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,StdErrLogTest.class.getName()));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.Bogus"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.resource.FileResource"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLoggingLevel_MixedLevels()
|
||||||
|
{
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty("org.eclipse.jetty.util.LEVEL","DEBUG");
|
||||||
|
props.setProperty("org.eclipse.jetty.util.ConcurrentHashMap.LEVEL","ALL");
|
||||||
|
|
||||||
|
// Default Levels
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.server.ServerObject"));
|
||||||
|
|
||||||
|
// Configured Level
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,StdErrLogTest.class.getName()));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.MagicUtil"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.resource.FileResource"));
|
||||||
|
Assert.assertEquals(StdErrLog.LEVEL_ALL,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.ConcurrentHashMap"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests StdErrLog.warn() methods with level filtering.
|
||||||
|
* <p>
|
||||||
|
* Should always see WARN level messages, regardless of set level.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWarnFiltering() throws UnsupportedEncodingException
|
||||||
{
|
{
|
||||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||||
log.setHideStacks(true);
|
log.setHideStacks(true);
|
||||||
|
|
||||||
Log.__ignored=false;
|
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||||
log.setDebugEnabled(false);
|
PrintStream err = new PrintStream(test);
|
||||||
|
log.setStdErrStream(err);
|
||||||
|
|
||||||
|
// Start with default level
|
||||||
|
log.warn("See Me");
|
||||||
|
|
||||||
|
// Set to debug level
|
||||||
|
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||||
|
log.warn("Hear Me");
|
||||||
|
|
||||||
|
// Set to warn level
|
||||||
|
log.setLevel(StdErrLog.LEVEL_WARN);
|
||||||
|
log.warn("Cheer Me");
|
||||||
|
|
||||||
|
// Validate Output
|
||||||
|
String output = new String(test.toByteArray(),"UTF-8");
|
||||||
|
System.err.print(output);
|
||||||
|
Assert.assertThat(output,containsString("See Me"));
|
||||||
|
Assert.assertThat(output,containsString("Hear Me"));
|
||||||
|
Assert.assertThat(output,containsString("Cheer Me"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests StdErrLog.info() methods with level filtering.
|
||||||
|
* <p>
|
||||||
|
* Should only see INFO level messages when level is set to {@link StdErrLog#LEVEL_INFO} and below.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testInfoFiltering() throws UnsupportedEncodingException
|
||||||
|
{
|
||||||
|
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||||
|
log.setHideStacks(true);
|
||||||
|
|
||||||
|
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||||
|
PrintStream err = new PrintStream(test);
|
||||||
|
log.setStdErrStream(err);
|
||||||
|
|
||||||
|
// Normal/Default behavior
|
||||||
|
log.info("I will not buy");
|
||||||
|
|
||||||
|
// Level Debug
|
||||||
|
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||||
|
log.info("this record");
|
||||||
|
|
||||||
|
// Level All
|
||||||
|
log.setLevel(StdErrLog.LEVEL_ALL);
|
||||||
|
log.info("it is scratched.");
|
||||||
|
|
||||||
|
// Level Warn
|
||||||
|
log.setLevel(StdErrLog.LEVEL_WARN);
|
||||||
|
log.info("sorry?");
|
||||||
|
|
||||||
|
// Validate Output
|
||||||
|
String output = new String(test.toByteArray(),"UTF-8");
|
||||||
|
System.err.print(output);
|
||||||
|
Assert.assertThat(output,containsString("I will not buy"));
|
||||||
|
Assert.assertThat(output,containsString("this record"));
|
||||||
|
Assert.assertThat(output,containsString("it is scratched."));
|
||||||
|
Assert.assertThat(output,not(containsString("sorry?")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests StdErrLog.debug() methods with level filtering.
|
||||||
|
* <p>
|
||||||
|
* Should only see DEBUG level messages when level is set to {@link StdErrLog#LEVEL_DEBUG} and below.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDebugFiltering() throws UnsupportedEncodingException
|
||||||
|
{
|
||||||
|
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||||
|
log.setHideStacks(true);
|
||||||
|
|
||||||
|
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||||
|
PrintStream err = new PrintStream(test);
|
||||||
|
log.setStdErrStream(err);
|
||||||
|
|
||||||
|
// Normal/Default behavior
|
||||||
|
log.debug("Tobacconist");
|
||||||
|
|
||||||
|
// Level Debug
|
||||||
|
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||||
|
log.debug("my hovercraft is");
|
||||||
|
|
||||||
|
// Level All
|
||||||
|
log.setLevel(StdErrLog.LEVEL_ALL);
|
||||||
|
log.debug("full of eels.");
|
||||||
|
|
||||||
|
// Level Warn
|
||||||
|
log.setLevel(StdErrLog.LEVEL_WARN);
|
||||||
|
log.debug("what?");
|
||||||
|
|
||||||
|
// Validate Output
|
||||||
|
String output = new String(test.toByteArray(),"UTF-8");
|
||||||
|
System.err.print(output);
|
||||||
|
Assert.assertThat(output,not(containsString("Tobacconist")));
|
||||||
|
Assert.assertThat(output,containsString("my hovercraft is"));
|
||||||
|
Assert.assertThat(output,containsString("full of eels."));
|
||||||
|
Assert.assertThat(output,not(containsString("what?")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests StdErrLog with {@link Logger#ignore(Throwable)} use.
|
||||||
|
* <p>
|
||||||
|
* Should only see IGNORED level messages when level is set to {@link StdErrLog#LEVEL_ALL}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testIgnores() throws UnsupportedEncodingException
|
||||||
|
{
|
||||||
|
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||||
|
log.setHideStacks(true);
|
||||||
|
|
||||||
|
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||||
|
PrintStream err = new PrintStream(test);
|
||||||
|
log.setStdErrStream(err);
|
||||||
|
|
||||||
|
// Normal/Default behavior
|
||||||
log.ignore(new Throwable("IGNORE ME"));
|
log.ignore(new Throwable("IGNORE ME"));
|
||||||
|
|
||||||
Log.__ignored=true;
|
// Show Ignored
|
||||||
log.setDebugEnabled(false);
|
log.setLevel(StdErrLog.LEVEL_ALL);
|
||||||
log.ignore(new Throwable("Don't ignore me"));
|
log.ignore(new Throwable("Don't ignore me"));
|
||||||
|
|
||||||
Log.__ignored=false;
|
// Set to Debug level
|
||||||
log.setDebugEnabled(true);
|
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||||
log.ignore(new Throwable("Debug me"));
|
log.ignore(new Throwable("Debug me"));
|
||||||
|
|
||||||
|
// Validate Output
|
||||||
|
String output = new String(test.toByteArray(),"UTF-8");
|
||||||
|
System.err.print(output);
|
||||||
|
Assert.assertThat(output,not(containsString("IGNORE ME")));
|
||||||
|
Assert.assertThat(output,containsString("Don't ignore me"));
|
||||||
|
Assert.assertThat(output,not(containsString("Debug me")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
pom.xml
1
pom.xml
|
@ -349,6 +349,7 @@
|
||||||
<module>jetty-nested</module>
|
<module>jetty-nested</module>
|
||||||
<module>jetty-overlay-deployer</module>
|
<module>jetty-overlay-deployer</module>
|
||||||
<module>jetty-nosql</module>
|
<module>jetty-nosql</module>
|
||||||
|
<module>jetty-http-spi</module>
|
||||||
<module>jetty-distribution</module>
|
<module>jetty-distribution</module>
|
||||||
<module>test-continuation</module>
|
<module>test-continuation</module>
|
||||||
<module>test-continuation-jetty6</module>
|
<module>test-continuation-jetty6</module>
|
||||||
|
|
Loading…
Reference in New Issue