You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by am...@apache.org on 2009/11/20 15:16:32 UTC
svn commit: r882564 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/
systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/
systests/jaxrs/src/...
Author: amichalec
Date: Fri Nov 20 14:16:31 2009
New Revision: 882564
URL: http://svn.apache.org/viewvc?rev=882564&view=rev
Log:
Spring integration of ATOM push-style logger; Log record JAXB namespace setup.
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/web.xml
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogLevel.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecord.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecordsList.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushBean.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngine.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/package-info.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogLevel.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogLevel.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogLevel.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogLevel.java Fri Nov 20 14:16:31 2009
@@ -38,29 +38,52 @@
*/
@XmlEnum
public enum LogLevel {
+ ALL,
FATAL,
ERROR,
WARN,
INFO,
DEBUG,
- TRACE;
-
+ TRACE,
+ OFF;
+
+ @XmlTransient
+ private static Map<Level, LogLevel> fromJul = new HashMap<Level, LogLevel>();
+
@XmlTransient
- private static Map<Level, LogLevel> julLogLevels = new HashMap<Level, LogLevel>();
+ private static Map<LogLevel, Level> toJul = new HashMap<LogLevel, Level>();
- static {
- julLogLevels.put(Level.SEVERE, LogLevel.ERROR);
- julLogLevels.put(Level.WARNING, LogLevel.WARN);
- julLogLevels.put(Level.INFO, LogLevel.INFO);
- julLogLevels.put(Level.FINE, LogLevel.DEBUG);
- julLogLevels.put(Level.FINER, LogLevel.DEBUG);
- julLogLevels.put(Level.FINEST, LogLevel.TRACE);
+ static {
+ fromJul.put(Level.ALL, LogLevel.ALL);
+ fromJul.put(Level.SEVERE, LogLevel.ERROR);
+ fromJul.put(Level.WARNING, LogLevel.WARN);
+ fromJul.put(Level.INFO, LogLevel.INFO);
+ fromJul.put(Level.FINE, LogLevel.DEBUG);
+ fromJul.put(Level.FINER, LogLevel.DEBUG);
+ fromJul.put(Level.FINEST, LogLevel.TRACE);
+ fromJul.put(Level.OFF, LogLevel.OFF);
+
+ toJul.put(LogLevel.ALL, Level.ALL);
+ toJul.put(LogLevel.FATAL, Level.SEVERE);
+ toJul.put(LogLevel.ERROR, Level.SEVERE);
+ toJul.put(LogLevel.WARN, Level.WARNING);
+ toJul.put(LogLevel.INFO, Level.INFO);
+ toJul.put(LogLevel.DEBUG, Level.FINE);
+ toJul.put(LogLevel.TRACE, Level.FINEST);
+ toJul.put(LogLevel.OFF, Level.OFF);
}
-
+
/**
* Creates this enum from JUL {@link Level}.
*/
public static LogLevel fromJUL(Level level) {
- return julLogLevels.get(level);
+ return fromJul.get(level);
+ }
+
+ /**
+ * Creates this JUL {@link Level} from this enum.
+ */
+ public static Level toJUL(LogLevel level) {
+ return toJul.get(level);
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecord.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecord.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecord.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecord.java Fri Nov 20 14:16:31 2009
@@ -39,7 +39,7 @@
* LogRecord are never null; if some attributes are not set (e.g. logger name, or rendered cause taken from
* Throwable) empty strings are returned.
*/
-@XmlRootElement
+@XmlRootElement(namespace = "http://cxf.apache.org/jaxrs/log")
public class LogRecord {
private Date eventTimestamp = new Date();
@@ -77,7 +77,7 @@
return record;
}
- @XmlElement
+ @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
public Date getEventTimestamp() {
return eventTimestamp;
}
@@ -87,7 +87,7 @@
this.eventTimestamp = eventTimestamp;
}
- @XmlElement
+ @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
public LogLevel getLevel() {
return level;
}
@@ -100,7 +100,7 @@
/**
* Formatted message with parameters filled in.
*/
- @XmlElement
+ @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
public String getMessage() {
return message;
}
@@ -110,7 +110,7 @@
this.message = renderedMessage;
}
- @XmlElement
+ @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
public String getLoggerName() {
return loggerName;
}
@@ -120,7 +120,7 @@
this.loggerName = loggerName;
}
- @XmlElement
+ @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
public String getThreadName() {
return threadName;
}
@@ -133,7 +133,7 @@
/**
* Full stack trace of {@link Throwable} associated with log record.
*/
- @XmlElement
+ @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
public String getThrowable() {
return throwable;
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecordsList.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecordsList.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecordsList.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecordsList.java Fri Nov 20 14:16:31 2009
@@ -33,12 +33,12 @@
/**
* List of {@link LogRecord}s. Necessary wrapper for {@link List} used in JAXB context.
*/
-@XmlRootElement(namespace = "zzz")
+@XmlRootElement(namespace = "http://cxf.apache.org/jaxrs/log")
public class LogRecordsList {
private List<LogRecord> logRecords = new ArrayList<LogRecord>();
-
- @XmlElement(name = "logRecord", namespace = "zzz")
+
+ @XmlElement(name = "logRecord", namespace = "http://cxf.apache.org/jaxrs/log")
public List<LogRecord> getLogRecords() {
return logRecords;
}
@@ -47,7 +47,7 @@
Validate.notNull(logRecords, "logRecords is null");
this.logRecords = logRecords;
}
-
+
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(obj, this);
@@ -61,5 +61,5 @@
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
- }
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushBean.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushBean.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushBean.java Fri Nov 20 14:16:31 2009
@@ -18,6 +18,234 @@
*/
package org.apache.cxf.jaxrs.ext.logging.atom;
-public class AtomPushBean {
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.logging.Handler;
+import java.util.logging.Logger;
+import org.apache.commons.lang.Validate;
+import org.apache.cxf.jaxrs.ext.logging.LogLevel;
+
+/**
+ * Bean used to configure {@link AtomPushHandler JUL handler} with Spring instead of properties file. Next to
+ * configuration of handler, Spring bean offers simple configuration of associated loggers that share ATOM
+ * push-style handler.
+ * <p>
+ * General rules:
+ * <ul>
+ * <li>When {@link #setDeliverer(Deliverer) deliverer} property is not set explicitly, URL must be set to
+ * create default deliverer.</li>
+ * <li>When {@link #setConverter(Converter) converter} property is not set explicitly, default converter is
+ * created.</li>
+ * <li>When {@link #setLoggers(String) loggers} property is used, it overrides pair of
+ * {@link #setLogger(String) logger} and {@link #setLevel(String) level} properties; and vice versa.</li>
+ * <li>When logger is not set, handler is attached to root logger (named ""); when level is not set for
+ * logger, default "INFO" level is used.</li>
+ * <li>When {@link #setBatchSize(String) batchSize} property is not set or set to wrong value, default batch
+ * size of "1" is used.</li>
+ * <li>When deliverer property is NOT set, use of "retryXxx" properties causes creation of retrying default
+ * deliverer.</li>
+ * </ul>
+ * Examples:
+ * <p>
+ * ATOM push handler with registered with root logger for all levels or log events, pushing one feed per event
+ * to specified URL, using default delivery and conversion methods:
+ *
+ * <pre>
+ * <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ * init-method="init">
+ * <property name="url" value="http://localhost:9080/feed"/>
+ * <property name="level" value="ALL" />
+ * </bean>
+ * </pre>
+ *
+ * ATOM push handler registered with multiple loggers and listening for different levels (see
+ * {@link #setLoggers(String) loggers} property description for syntax details). Custom deliverer will take
+ * care of feeds, each of which carries batch of 10 log events:
+ *
+ * <pre>
+ * <bean id="soapDeliverer" ...
+ * ...
+ * <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ * init-method="init">
+ * <property name="deliverer">
+ * <ref bean="soapDeliverer"/>
+ * </property>
+ * <property name="loggers" value="
+ * org.apache.cxf:DEBUG,
+ * org.apache.cxf.jaxrs,
+ * org.apache.cxf.bus:ERROR" />
+ * <property name="batchSize" value="10" />
+ * </bean>
+ * </pre>
+ */
+public final class AtomPushBean {
+
+ private AtomPushEngineConfigurator conf = new AtomPushEngineConfigurator();
+ private List<LoggerLevel> loggers = new ArrayList<LoggerLevel>();
+ private boolean initialized;
+
+ /**
+ * Creates unconfigured and uninitialized bean. To configure setters must be used, then {@link #init()}
+ * must be called.
+ */
+ public AtomPushBean() {
+ initSingleLogger();
+ }
+
+ private void initSingleLogger() {
+ loggers = new ArrayList<LoggerLevel>();
+ loggers.add(new LoggerLevel("", "INFO"));
+ }
+
+ /**
+ * Set URL used when custom deliverer is not set (default deliverer is being created).
+ */
+ public void setUrl(String url) {
+ checkInit();
+ Validate.notNull(url, "url is null");
+ conf.setUrl(url);
+ }
+
+ /**
+ * Set initialized deliverer.
+ */
+ public void setDeliverer(Deliverer deliverer) {
+ checkInit();
+ Validate.notNull(deliverer, "deliverer is null");
+ conf.setDeliverer(deliverer);
+ }
+
+ /**
+ * Set initialized converter.
+ */
+ public void setConverter(Converter converter) {
+ checkInit();
+ Validate.notNull(converter, "converter is null");
+ conf.setConverter(converter);
+ }
+
+ /**
+ * Set one or more loggers and levels descriptor. <br>
+ * Parsed input syntax is:
+ *
+ * <pre>
+ * loggers := <logger>(<separator><logger>)*
+ * logger := <name>[":"<level>]
+ * separator := "," | " " | "\n"
+ * </pre>
+ *
+ * Examples:
+ * <p>
+ * Two loggers and two levels: <br>
+ * <tt>org.apache.cxf:INFO, org.apache.cxf.jaxrs:DEBUG</tt>
+ * <p>
+ * Three loggers, first with default "INFO" level: <br>
+ * <tt>org.apache.cxf, org.apache.cxf.jaxrs:DEBUG, namedLogger:ERROR</tt><br>
+ * <p>
+ * One logger with default "INFO" level: <br>
+ * <tt>org.apache.cxf</tt><br>
+ */
+ public void setLoggers(String loggers) {
+ checkInit();
+ Validate.notNull(loggers, "loggers is null");
+ parseLoggers(loggers);
+ }
+
+ /**
+ * Name of logger to associate with ATOM push handler; empty string for root logger.
+ */
+ public void setLogger(String logger) {
+ checkInit();
+ Validate.notNull(logger, "logger is null");
+ if (loggers.size() != 1) {
+ initSingleLogger();
+ }
+ loggers.get(0).setLogger(logger);
+ }
+
+ /**
+ * Name of level that logger will use publishing log events to ATOM push handler; empty string for default
+ * "INFO" level.
+ */
+ public void setLevel(String level) {
+ checkInit();
+ Validate.notNull(level, "level is null");
+ if (loggers.size() != 1) {
+ initSingleLogger();
+ }
+ loggers.get(0).setLevel(level);
+ }
+
+ /**
+ * Size of batch; empty string for default one element batch.
+ */
+ public void setBatchSize(String batchSize) {
+ checkInit();
+ Validate.notNull(batchSize, "batchSize is null");
+ conf.setBatchSize(batchSize);
+ }
+
+ /**
+ * Initializes bean; creates ATOM push handler based on current properties state, and attaches handler to
+ * logger(s).
+ */
+ public void init() {
+ checkInit();
+ initialized = true;
+ Handler h = new AtomPushHandler(conf.createEngine());
+ for (int i = 0; i < loggers.size(); i++) {
+ Logger l = Logger.getLogger(loggers.get(i).getLogger());
+ l.addHandler(h);
+ l.setLevel(LogLevel.toJUL(LogLevel.valueOf(loggers.get(i).getLevel())));
+ }
+ }
+
+ private void checkInit() {
+ if (initialized) {
+ throw new IllegalStateException("Bean is already initialized");
+ }
+ }
+
+ private void parseLoggers(String param) {
+ loggers = new ArrayList<LoggerLevel>();
+ StringTokenizer st1 = new StringTokenizer(param, ", \t\n\r\f");
+ while (st1.hasMoreTokens()) {
+ String tok = st1.nextToken();
+ int idx = tok.indexOf(":");
+ if (idx != -1) {
+ loggers.add(new LoggerLevel(tok.substring(0, idx), tok.substring(idx + 1, tok.length())));
+ } else {
+ loggers.add(new LoggerLevel(tok, "INFO"));
+ }
+ }
+ }
+
+ private static class LoggerLevel {
+ private String logger;
+ private String level;
+
+ public LoggerLevel(String logger, String level) {
+ this.logger = logger;
+ this.level = level;
+ }
+
+ public String getLogger() {
+ return logger;
+ }
+
+ public void setLogger(String logger) {
+ this.logger = logger;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngine.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngine.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngine.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngine.java Fri Nov 20 14:16:31 2009
@@ -28,7 +28,7 @@
import org.apache.cxf.jaxrs.ext.logging.LogRecord;
/**
- * ATOM push-style realization class. Engine enqueues log records as they are {@link #publish(LogRecord)
+ * Package private ATOM push-style engine. Engine enqueues log records as they are {@link #publish(LogRecord)
* published}. After queue size exceeds {@link #getBatchSize() batch size} processing of collection of these
* records (in size of batch size) is triggered.
* <p>
@@ -44,7 +44,7 @@
* reliable deliverer or use wrapping {@link RetryingDeliverer}.
*/
// TODO add internal diagnostics - log messages somewhere except for logger :D
-public class AtomPushEngine {
+final class AtomPushEngine {
private List<LogRecord> queue = new ArrayList<LogRecord>();
private ExecutorService executor = Executors.newSingleThreadExecutor();
private int batchSize = 1;
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java?rev=882564&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java Fri Nov 20 14:16:31 2009
@@ -0,0 +1,161 @@
+/**
+ * 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.cxf.jaxrs.ext.logging.atom;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Package private interpreter of incomplete input of engine configuration. Used commonly by
+ * {@link AtomPushHandler properties file} and {@link AtomPushBean spring} configuration schemes.
+ */
+// TODO extract 'general rules' of interpretation in handler and bean and put here
+final class AtomPushEngineConfigurator {
+
+ private Deliverer deliverer;
+ private Converter converter;
+ private String delivererClass;
+ private String converterClass;
+ private String batchSize;
+ private String delivererUrl;
+ private String retryTimeout;
+ private String retryPauseType;
+ private String retryPauseTime;
+
+ public void setUrl(String url) {
+ this.delivererUrl = url;
+ }
+
+ public void setRetryTimeout(String retryTimeout) {
+ this.retryTimeout = retryTimeout;
+ }
+
+ public void setRetryPauseType(String retryPauseType) {
+ this.retryPauseType = retryPauseType;
+ }
+
+ public void setRetryPauseTime(String retryPauseTime) {
+ this.retryPauseTime = retryPauseTime;
+ }
+
+ public void setBatchSize(String batchSize) {
+ this.batchSize = batchSize;
+ }
+
+ public void setDeliverer(Deliverer deliverer) {
+ this.deliverer = deliverer;
+ }
+
+ public void setConverter(Converter converter) {
+ this.converter = converter;
+ }
+
+ public void setDelivererClass(String delivererClass) {
+ this.delivererClass = delivererClass;
+ }
+
+ public void setConverterClass(String converterClass) {
+ this.converterClass = converterClass;
+ }
+
+ public AtomPushEngine createEngine() {
+ Deliverer d = deliverer;
+ Converter c = converter;
+ int batch = 1;
+ if (d == null) {
+ if (delivererUrl != null) {
+ if (delivererClass != null) {
+ d = createDeliverer(delivererClass, delivererUrl);
+ } else {
+ d = new WebClientDeliverer(delivererUrl);
+ }
+ } else {
+ throw new IllegalStateException("Either url, deliverer or "
+ + "deliverer class with url must be setup");
+ }
+ }
+ if (c == null) {
+ if (converterClass != null) {
+ c = createConverter(converterClass);
+ } else {
+ c = new ContentSingleEntryConverter();
+ }
+ }
+ batch = parseInt(batchSize, 1, 1);
+ if (retryPauseType != null) {
+ int timeout = parseInt(retryTimeout, 0, 0);
+ int pause = parseInt(retryPauseTime, 1, 30);
+ boolean linear = !retryPauseType.equalsIgnoreCase("exponential");
+ d = new RetryingDeliverer(d, timeout, pause, linear);
+ }
+ AtomPushEngine engine = new AtomPushEngine();
+ engine.setDeliverer(d);
+ engine.setConverter(c);
+ engine.setBatchSize(batch);
+ return engine;
+ }
+
+ private Deliverer createDeliverer(String clazz, String url) {
+ try {
+ Constructor<?> ctor = loadClass(clazz).getConstructor(String.class);
+ return (Deliverer)ctor.newInstance(url);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private Converter createConverter(String clazz) {
+ try {
+ Constructor<?> ctor = loadClass(clazz).getConstructor();
+ return (Converter)ctor.newInstance();
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private Class<?> loadClass(String clazz) throws ClassNotFoundException {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ return cl.loadClass(clazz);
+ } catch (ClassNotFoundException e) {
+ try {
+ // clazz could be shorted (stripped package name) retry
+ String clazz2 = getClass().getPackage().getName() + "." + clazz;
+ return cl.loadClass(clazz2);
+ } catch (Exception e1) {
+ throw new ClassNotFoundException(e.getMessage() + " or " + e1.getMessage());
+ }
+ }
+ }
+
+ private int parseInt(String property, int defaultValue) {
+ try {
+ return Integer.parseInt(property);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+
+ private int parseInt(String property, int lessThan, int defaultValue) {
+ int ret = parseInt(property, defaultValue);
+ if (ret < lessThan) {
+ ret = defaultValue;
+ }
+ return ret;
+ }
+}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java Fri Nov 20 14:16:31 2009
@@ -18,7 +18,6 @@
*/
package org.apache.cxf.jaxrs.ext.logging.atom;
-import java.lang.reflect.Constructor;
import java.util.logging.Handler;
import java.util.logging.LogManager;
@@ -73,7 +72,7 @@
*/
public final class AtomPushHandler extends Handler {
- private AtomPushEngine engine = new AtomPushEngine();
+ private AtomPushEngine engine;
private boolean lazyConfig;
/**
@@ -93,11 +92,21 @@
* @param deliverer deliverer pushing ATOM elements to client
*/
public AtomPushHandler(int batchSize, Converter converter, Deliverer deliverer) {
+ engine = new AtomPushEngine();
engine.setBatchSize(batchSize);
engine.setConverter(converter);
engine.setDeliverer(deliverer);
}
+ /**
+ * Creates handler using (package private).
+ *
+ * @param engine configured engine.
+ */
+ AtomPushHandler(AtomPushEngine engine) {
+ this.engine = engine;
+ }
+
@Override
public synchronized void publish(java.util.logging.LogRecord record) {
if (LoggingThread.isSilent()) {
@@ -107,7 +116,7 @@
try {
if (lazyConfig) {
lazyConfig = false;
- configure();
+ configure2();
}
LogRecord rec = LogRecord.fromJUL(record);
engine.publish(rec);
@@ -132,84 +141,97 @@
* does not allow to iterate over configuration properties to make interpretation automated (e.g. using
* commons-beanutils)
*/
- private void configure() {
+ // private void configure() {
+ // LogManager manager = LogManager.getLogManager();
+ // String cname = getClass().getName();
+ // String url = manager.getProperty(cname + ".url");
+ // if (url == null) {
+ // // cannot proceed
+ // return;
+ // }
+ // String deliverer = manager.getProperty(cname + ".deliverer");
+ // if (deliverer != null) {
+ // engine.setDeliverer(createDeliverer(deliverer, url));
+ // } else {
+ // // default
+ // engine.setDeliverer(new WebClientDeliverer(url));
+ // }
+ // String converter = manager.getProperty(cname + ".converter");
+ // if (converter != null) {
+ // engine.setConverter(createConverter(converter));
+ // } else {
+ // // default
+ // engine.setConverter(new ContentSingleEntryConverter());
+ // }
+ // engine.setBatchSize(toInt(manager.getProperty(cname + ".batchSize"), 1, 1));
+ // String retryType = manager.getProperty(cname + ".retry.pause");
+ // if (retryType != null) {
+ // int timeout = toInt(manager.getProperty(cname + ".retry.timeout"), 0, 0);
+ // int pause = toInt(manager.getProperty(cname + ".retry.pause.time"), 1, 30);
+ // boolean linear = !retryType.equalsIgnoreCase("exponential");
+ // Deliverer wrapped = new RetryingDeliverer(engine.getDeliverer(), timeout, pause, linear);
+ // engine.setDeliverer(wrapped);
+ // }
+ // }
+ private void configure2() {
LogManager manager = LogManager.getLogManager();
String cname = getClass().getName();
- String url = manager.getProperty(cname + ".url");
- if (url == null) {
- // cannot proceed
- return;
- }
- String deliverer = manager.getProperty(cname + ".deliverer");
- if (deliverer != null) {
- engine.setDeliverer(createDeliverer(deliverer, url));
- } else {
- // default
- engine.setDeliverer(new WebClientDeliverer(url));
- }
- String converter = manager.getProperty(cname + ".converter");
- if (converter != null) {
- engine.setConverter(createConverter(converter));
- } else {
- // default
- engine.setConverter(new ContentSingleEntryConverter());
- }
- engine.setBatchSize(toInt(manager.getProperty(cname + ".batchSize"), 1, 1));
- String retryType = manager.getProperty(cname + ".retry.pause");
- if (retryType != null) {
- int timeout = toInt(manager.getProperty(cname + ".retry.timeout"), 0, 0);
- int pause = toInt(manager.getProperty(cname + ".retry.pause.time"), 1, 30);
- boolean linear = !retryType.equalsIgnoreCase("exponential");
- Deliverer wrapped = new RetryingDeliverer(engine.getDeliverer(), timeout, pause, linear);
- engine.setDeliverer(wrapped);
- }
- }
-
- private int toInt(String property, int defaultValue) {
- try {
- return Integer.parseInt(property);
- } catch (NumberFormatException e) {
- return defaultValue;
- }
- }
-
- private int toInt(String property, int lessThan, int defaultValue) {
- int ret = toInt(property, defaultValue);
- if (ret < lessThan) {
- ret = defaultValue;
- }
- return ret;
- }
-
- private Deliverer createDeliverer(String clazz, String url) {
- try {
- Constructor<?> ctor = loadClass(clazz).getConstructor(String.class);
- return (Deliverer)ctor.newInstance(url);
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private Converter createConverter(String clazz) {
- try {
- Constructor<?> ctor = loadClass(clazz).getConstructor();
- return (Converter)ctor.newInstance();
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private Class<?> loadClass(String clazz) throws ClassNotFoundException {
- try {
- return getClass().getClassLoader().loadClass(clazz);
- } catch (ClassNotFoundException e) {
- try {
- // clazz could be shorted (stripped package name) retry
- String clazz2 = getClass().getPackage().getName() + "." + clazz;
- return getClass().getClassLoader().loadClass(clazz2);
- } catch (Exception e1) {
- throw new ClassNotFoundException(e.getMessage() + " or " + e1.getMessage());
- }
- }
- }
+ AtomPushEngineConfigurator conf = new AtomPushEngineConfigurator();
+ conf.setUrl(manager.getProperty(cname + ".url"));
+ conf.setDelivererClass(manager.getProperty(cname + ".deliverer"));
+ conf.setConverterClass(manager.getProperty(cname + ".converter"));
+ conf.setBatchSize(manager.getProperty(cname + ".batchSize"));
+ conf.setRetryPauseType(manager.getProperty(cname + ".retry.pause"));
+ conf.setRetryPauseTime(manager.getProperty(cname + ".retry.pause.time"));
+ conf.setRetryTimeout(manager.getProperty(cname + ".retry.timeout"));
+ engine = conf.createEngine();
+ }
+
+// private int toInt(String property, int defaultValue) {
+// try {
+// return Integer.parseInt(property);
+// } catch (NumberFormatException e) {
+// return defaultValue;
+// }
+// }
+//
+// private int toInt(String property, int lessThan, int defaultValue) {
+// int ret = toInt(property, defaultValue);
+// if (ret < lessThan) {
+// ret = defaultValue;
+// }
+// return ret;
+// }
+//
+// private Deliverer createDeliverer(String clazz, String url) {
+// try {
+// Constructor<?> ctor = loadClass(clazz).getConstructor(String.class);
+// return (Deliverer)ctor.newInstance(url);
+// } catch (Exception e) {
+// throw new IllegalArgumentException(e);
+// }
+// }
+//
+// private Converter createConverter(String clazz) {
+// try {
+// Constructor<?> ctor = loadClass(clazz).getConstructor();
+// return (Converter)ctor.newInstance();
+// } catch (Exception e) {
+// throw new IllegalArgumentException(e);
+// }
+// }
+//
+// private Class<?> loadClass(String clazz) throws ClassNotFoundException {
+// try {
+// return getClass().getClassLoader().loadClass(clazz);
+// } catch (ClassNotFoundException e) {
+// try {
+// // clazz could be shorted (stripped package name) retry
+// String clazz2 = getClass().getPackage().getName() + "." + clazz;
+// return getClass().getClassLoader().loadClass(clazz2);
+// } catch (Exception e1) {
+// throw new ClassNotFoundException(e.getMessage() + " or " + e1.getMessage());
+// }
+// }
+// }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java Fri Nov 20 14:16:31 2009
@@ -26,7 +26,7 @@
* Other approach than using thread local storage would be scanning of stack trace of current thread to see if
* root of call comes from same package as package of handler - it's less effective so TLS is using here.
*/
-public final class LoggingThread {
+final class LoggingThread {
private static ThreadLocal<LoggingThread> threadLocal = new ThreadLocal<LoggingThread>() {
@Override
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/package-info.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/package-info.java?rev=882564&r1=882563&r2=882564&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/package-info.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/package-info.java Fri Nov 20 14:16:31 2009
@@ -24,5 +24,8 @@
* to this implementation applying <a href="www.slf4j.org">SLF4J</a>
* that JAXRS already depends on.
*/
+@javax.xml.bind.annotation.XmlSchema(xmlns = {
+ @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://cxf.apache.org/jaxrs/log", prefix = "log")
+ })
package org.apache.cxf.jaxrs.ext.logging;
Added: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java?rev=882564&view=auto
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java (added)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java Fri Nov 20 14:16:31 2009
@@ -0,0 +1,110 @@
+/**
+ * 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.cxf.systest.jaxrs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.apache.abdera.model.Feed;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.testutil.common.AbstractClientServerTestBase;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class JAXRSLoggingAtomPushSpringTest extends AbstractClientServerTestBase {
+
+ private static List<Feed> retrieved = new ArrayList<Feed>();
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ // must be 'in-process' to communicate with inner class in single JVM
+ // and to spawn class SpringServer w/o using main() method
+ launchServer(SpringServer.class, true);
+ }
+
+ @Ignore
+ public static class SpringServer extends AbstractSpringServer {
+ public SpringServer() {
+ super("/jaxrs_logging_atompush");
+ }
+ }
+
+ @Before
+ public void before() {
+ retrieved.clear();
+ }
+
+ @Ignore
+ @Path("/")
+ public static class Resource {
+ private static final Logger LOG1 = LogUtils.getL7dLogger(Resource.class);
+ private static final Logger LOG2 = LogUtils.getL7dLogger(Resource.class, null, "namedLogger");
+
+ @GET
+ @Path("/log")
+ public void doLogging() {
+ LOG1.severe("severe message");
+ LOG1.warning("warning message");
+ LOG1.info("info message");
+ LogRecord r = new LogRecord(Level.FINE, "fine message");
+ r.setThrown(new IllegalArgumentException("tadaam"));
+ LOG1.log(r);
+ r = new LogRecord(Level.FINER, "finer message with {0} and {1}");
+ r.setParameters(new Object[] {
+ "param1", "param2"
+ });
+ r.setLoggerName("faky-logger");
+ LOG1.log(r);
+ LOG1.finest("finest message");
+
+ // for LOG2 only 'warning' and above messages should be logged
+ LOG2.severe("severe message");
+ LOG2.info("info message - should not pass!");
+ LOG2.finer("finer message - should not pass!");
+ }
+
+ // 2. ATOM push handler should populate logs here
+ @POST
+ @Path("/feed")
+ public void consume(Feed feed) {
+ // System.out.println(feed);
+ retrieved.add(feed);
+ }
+
+ }
+
+ @Test
+ public void testLogEvents() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:9080");
+ wc.path("/log").get();
+ Thread.sleep(1000);
+ assertEquals(7, retrieved.size());
+ }
+}
Added: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml?rev=882564&view=auto
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml (added)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml Fri Nov 20 14:16:31 2009
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ 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.
+ -->
+ <!-- START SNIPPET: beans -->
+ <!--
+ beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:simple="http://cxf.apache.org/simple" xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd"
+ -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+http://www.springframework.org/schema/beans
+http://www.springframework.org/schema/beans/spring-beans.xsd
+http://cxf.apache.org/jaxrs
+http://cxf.apache.org/schemas/jaxrs.xsd">
+
+ <import resource="classpath:META-INF/cxf/cxf.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
+
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+ <property name="url" value="http://localhost:9080/feed" />
+ <!-- Mind the '$' instead of '.' for inner classes! -->
+ <property name="loggers"
+ value="
+ org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource:ALL,
+ namedLogger:WARN" />
+ </bean>
+
+ <!--
+ Other config samples:
+
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+
+ <property name="url" value="http://localhost:9080/feed" />
+ <property name="level" value="ALL" />
+ </bean>
+
+ <bean id="soapDeliverer" ... />
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+ <property name="deliverer">
+ <ref bean="soapDeliverer" />
+ </property>
+ <property name="loggers"
+ value="
+ org.apache.cxf:DEBUG,
+ org.apache.cxf.jaxrs:ALL,
+ org.apache.cxf.bus:WARNING" />
+ <property name="batchSize" value="10" />
+ </bean>
+ -->
+
+ <jaxrs:server id="atomserver" address="/">
+ <jaxrs:serviceBeans>
+ <ref bean="atombean" />
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="feed" />
+ <ref bean="entry" />
+ </jaxrs:providers>
+ </jaxrs:server>
+
+ <!-- Mind the '$' instead of '.' for inner classes! -->
+ <bean id="atombean"
+ class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource" />
+ <bean id="feed" class="org.apache.cxf.jaxrs.provider.AtomFeedProvider" />
+ <bean id="entry" class="org.apache.cxf.jaxrs.provider.AtomEntryProvider" />
+
+</beans>
+ <!-- END SNIPPET: beans -->
+
Added: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/web.xml?rev=882564&view=auto
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/web.xml (added)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/web.xml Fri Nov 20 14:16:31 2009
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+<!--
+ 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.
+-->
+<!-- START SNIPPET: webxml -->
+<web-app>
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>WEB-INF/beans.xml</param-value>
+ </context-param>
+
+ <listener>
+ <listener-class>
+ org.springframework.web.context.ContextLoaderListener
+ </listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>CXFServlet</servlet-name>
+ <display-name>CXF Servlet</display-name>
+ <servlet-class>
+ org.apache.cxf.transport.servlet.CXFServlet
+ </servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>CXFServlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
+<!-- END SNIPPET: webxml -->