You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2009/12/03 23:27:02 UTC
svn commit: r886957 [3/5] - in /cxf/trunk:
api/src/test/java/org/apache/cxf/databinding/
distribution/src/main/release/samples/wsdl_first/src/main/java/com/example/customerservice/client/
distribution/src/main/release/samples/wsdl_first/src/main/java/c...
Modified: 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=886957&r1=886956&r2=886957&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java Thu Dec 3 22:26:58 2009
@@ -1,201 +1,201 @@
-/**
- * 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;
-
-import org.apache.cxf.jaxrs.ext.logging.atom.converter.Converter;
-import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter;
-import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter.Format;
-import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter.Multiplicity;
-import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter.Output;
-import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.Deliverer;
-import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.RetryingDeliverer;
-import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.WebClientDeliverer;
-
-/**
- * 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 retryPause;
- private String retryPauseTime;
- private String output;
- private String multiplicity;
- private String format;
-
- public void setUrl(String url) {
- this.delivererUrl = url;
- }
-
- public void setRetryTimeout(String retryTimeout) {
- this.retryTimeout = retryTimeout;
- }
-
- public void setRetryPause(String retryPause) {
- this.retryPause = retryPause;
- }
-
- 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 void setOutput(String output) {
- this.output = output;
- }
-
- public void setMultiplicity(String multiplicity) {
- this.multiplicity = multiplicity;
- }
-
- public void setFormat(String format) {
- this.format = format;
- }
-
- public AtomPushEngine createEngine() {
- Deliverer d = deliverer;
- Converter c = converter;
- int batch = parseInt(batchSize, 1, 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 {
- Output out = parseEnum(output, Output.FEED);
- Multiplicity mul = parseEnum(multiplicity, Multiplicity.ONE);
- Format form = parseEnum(format, Format.CONTENT);
- c = new StandardConverter(out, mul, form);
- if (retryPause != null) {
- int timeout = parseInt(retryTimeout, 0, 0);
- int pause = parseInt(retryPauseTime, 1, 30);
- boolean linear = !retryPause.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<Deliverer> ctor = loadClass(clazz, Deliverer.class).getConstructor(String.class);
- return ctor.newInstance(url);
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private Converter createConverter(String clazz) {
- try {
- Constructor<Converter> ctor = loadClass(clazz, Converter.class).getConstructor();
- return ctor.newInstance();
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- private <T> Class<T> loadClass(String clazz, Class<T> ifaceClass) throws ClassNotFoundException {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- try {
- return (Class<T>)cl.loadClass(clazz);
- } catch (ClassNotFoundException e) {
- try {
- // clazz could be shorted (stripped package name) retry for interface location
- String pkg = ifaceClass.getPackage().getName();
- String clazz2 = pkg + "." + clazz;
- return (Class<T>)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;
- }
-
- @SuppressWarnings("unchecked")
- private <T extends Enum<T>> T parseEnum(String value, T defaultValue) {
- if (value == null | "".equals(value)) {
- return defaultValue;
- }
- try {
- return (T)Enum.valueOf(defaultValue.getClass(), value.toUpperCase());
- } catch (Exception e) {
- return defaultValue;
- }
- }
-}
+/**
+ * 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;
+
+import org.apache.cxf.jaxrs.ext.logging.atom.converter.Converter;
+import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter;
+import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter.Format;
+import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter.Multiplicity;
+import org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter.Output;
+import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.Deliverer;
+import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.RetryingDeliverer;
+import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.WebClientDeliverer;
+
+/**
+ * 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 retryPause;
+ private String retryPauseTime;
+ private String output;
+ private String multiplicity;
+ private String format;
+
+ public void setUrl(String url) {
+ this.delivererUrl = url;
+ }
+
+ public void setRetryTimeout(String retryTimeout) {
+ this.retryTimeout = retryTimeout;
+ }
+
+ public void setRetryPause(String retryPause) {
+ this.retryPause = retryPause;
+ }
+
+ 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 void setOutput(String output) {
+ this.output = output;
+ }
+
+ public void setMultiplicity(String multiplicity) {
+ this.multiplicity = multiplicity;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public AtomPushEngine createEngine() {
+ Deliverer d = deliverer;
+ Converter c = converter;
+ int batch = parseInt(batchSize, 1, 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 {
+ Output out = parseEnum(output, Output.FEED);
+ Multiplicity mul = parseEnum(multiplicity, Multiplicity.ONE);
+ Format form = parseEnum(format, Format.CONTENT);
+ c = new StandardConverter(out, mul, form);
+ if (retryPause != null) {
+ int timeout = parseInt(retryTimeout, 0, 0);
+ int pause = parseInt(retryPauseTime, 1, 30);
+ boolean linear = !retryPause.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<Deliverer> ctor = loadClass(clazz, Deliverer.class).getConstructor(String.class);
+ return ctor.newInstance(url);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private Converter createConverter(String clazz) {
+ try {
+ Constructor<Converter> ctor = loadClass(clazz, Converter.class).getConstructor();
+ return ctor.newInstance();
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> Class<T> loadClass(String clazz, Class<T> ifaceClass) throws ClassNotFoundException {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ return (Class<T>)cl.loadClass(clazz);
+ } catch (ClassNotFoundException e) {
+ try {
+ // clazz could be shorted (stripped package name) retry for interface location
+ String pkg = ifaceClass.getPackage().getName();
+ String clazz2 = pkg + "." + clazz;
+ return (Class<T>)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;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Enum<T>> T parseEnum(String value, T defaultValue) {
+ if (value == null | "".equals(value)) {
+ return defaultValue;
+ }
+ try {
+ return (T)Enum.valueOf(defaultValue.getClass(), value.toUpperCase());
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushEngineConfigurator.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=886957&r1=886956&r2=886957&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 Thu Dec 3 22:26:58 2009
@@ -1,184 +1,184 @@
-/**
- * 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.util.logging.Handler;
-import java.util.logging.LogManager;
-
-import org.apache.cxf.jaxrs.ext.logging.LogRecord;
-import org.apache.cxf.jaxrs.ext.logging.atom.converter.Converter;
-import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.Deliverer;
-
-/**
- * Handler pushing log records in batches as Atom Feeds or Entries to registered client. Handler
- * responsibility is to adapt to JUL framework while most of job is delegated to {@link AtomPushEngine}.
- * <p>
- * For simple configuration using properties file (one global root-level handler of this class) following
- * properties prefixed with full name of this class can be used:
- * <ul>
- * <li><b>url</b> - URL where feeds will be pushed (mandatory parameter)</li>
- * <li><b>batchSize</b> - integer number specifying minimal number of published log records that trigger
- * processing and pushing ATOM document. If parameter is not set, is not greater than zero or is not a number,
- * batch size is set to 1.</li>
- * </ul>
- * Conversion of log records into ATOM Elements can be tuned up using following parameters. Note that not all
- * combinations are meaningful, see {@link org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter}
- * for details:
- * <ul>
- * <li><b>output</b> - ATOM Element type pushed out, either "feed" or "entry"; when not specified or invalid
- * value provided "feed" is used.</li>
- * <li><b>multiplicity</b> - multiplicity of subelement(entries in feed for output=="feed" or log records in
- * entry for output=="entry"), either "one" or "many"; when not specified or invalid value provided "one" is
- * used.</li>
- * <li><b>format</b> - method of embedding data in entry, either "content" or "extension"; when not specified
- * or invalid value provided "content" is used.</li>
- * </ul>
- * By default delivery is served by WebClientDeliverer which does not support reliability of transport.
- * Availability of any of this parameters enables retrying of default delivery. Detailed explanation of these
- * parameter, see {@link org.apache.cxf.jaxrs.ext.logging.atom.deliverer.RetryingDeliverer} class description.
- * <ul>
- * <li><b>retry.pause</b> - pausing strategy of delivery retries, either <b>linear</b> or <b>exponential</b>
- * value (mandatory parameter). If mispelled linear is used.</li>
- * <li><b>retry.pause.time</b> - pause time (in seconds) between retries. If parameter is not set, pause is
- * set to 30 seconds.</li>
- * <li><b>retry.timeout</b> - maximum time (in seconds) retrying will be continued. If not set timeout is not
- * set (infinite loop of retries).</li>
- * </ul>
- * Ultimate control on conversion and delivery is obtained specifying own implementation classes:
- * <ul>
- * <li><b>converter</b> - name of class implementing {@link Converter} class replacing default conversion and
- * its specific parameters ("output", "multiplicity" and "format") are ignored. For classes located in same
- * package as Converter interface only class name can be given e.g. instead of
- * "org.apache.cxf.jaxrs.ext.logging.atom.converter.FooBarConverter" one can specify "FooBarConverter".</li>
- * <li><b>deliverer</b> - name of class implementing {@link Deliverer} class replacing default delivery and
- * its specific parameters ("retry.Xxx") are ignored. For classes located in same package as Deliverer
- * interface only class name can be given e.g. instead of
- * "org.apache.cxf.jaxrs.ext.logging.atom.deliverer.WebClientDeliverer" one can specify
- * "WebClientDeliverer".</li>
- * </ul>
- * Example:
- *
- * <pre>
- * handlers = org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler, java.util.logging.ConsoleHandler
- * .level = INFO
- *
- * # deliver to given URL triggering after each batch of 10 log records
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.url = http://localhost:9080
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.batchSize = 10
- *
- * # enable retrying delivery every 10 seconds for 5 minutes
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.retry.pause = linear
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.retry.pause.time = 10
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.retry.timeout = 300
- *
- * # output for AtomPub: push entries not feeds, each entry with one log record as "atom:extension"
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.output = entry
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.multiplicity = one
- * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.format = extension
- * ...
- * </pre>
- */
-public final class AtomPushHandler extends Handler {
-
- private AtomPushEngine engine;
- private boolean lazyConfig;
-
- /**
- * Creates handler with configuration taken from properties file.
- */
- public AtomPushHandler() {
- // deferred configuration: configure() called from here would use utilities that attempt to log
- // and create this handler instance in recursion; configure() will be called on first publish()
- lazyConfig = true;
- }
-
- /**
- * Creates handler with custom parameters.
- *
- * @param batchSize batch size, see {@link AtomPushEngine#getBatchSize()}
- * @param converter converter transforming logs into ATOM elements
- * @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()) {
- return;
- }
- LoggingThread.markSilent(true);
- try {
- if (lazyConfig) {
- lazyConfig = false;
- configure();
- }
- LogRecord rec = LogRecord.fromJUL(record);
- engine.publish(rec);
- } finally {
- LoggingThread.markSilent(false);
- }
- }
-
- @Override
- public synchronized void close() throws SecurityException {
- engine.shutdown();
- }
-
- @Override
- public synchronized void flush() {
- // no-op
- }
-
- /**
- * Configuration from properties. Aligned to JUL strategy - properties file is only for simple
- * configuration: it allows configure one root handler with its parameters. What is even more dummy, JUL
- * does not allow to iterate over configuration properties to make interpretation automated (e.g. using
- * commons-beanutils)
- */
- private void configure() {
- LogManager manager = LogManager.getLogManager();
- String cname = getClass().getName();
- 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.setRetryPause(manager.getProperty(cname + ".retry.pause"));
- conf.setRetryPauseTime(manager.getProperty(cname + ".retry.pause.time"));
- conf.setRetryTimeout(manager.getProperty(cname + ".retry.timeout"));
- conf.setOutput(manager.getProperty(cname + ".output"));
- conf.setMultiplicity(manager.getProperty(cname + ".multiplicity"));
- conf.setFormat(manager.getProperty(cname + ".format"));
- engine = conf.createEngine();
- }
-}
+/**
+ * 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.util.logging.Handler;
+import java.util.logging.LogManager;
+
+import org.apache.cxf.jaxrs.ext.logging.LogRecord;
+import org.apache.cxf.jaxrs.ext.logging.atom.converter.Converter;
+import org.apache.cxf.jaxrs.ext.logging.atom.deliverer.Deliverer;
+
+/**
+ * Handler pushing log records in batches as Atom Feeds or Entries to registered client. Handler
+ * responsibility is to adapt to JUL framework while most of job is delegated to {@link AtomPushEngine}.
+ * <p>
+ * For simple configuration using properties file (one global root-level handler of this class) following
+ * properties prefixed with full name of this class can be used:
+ * <ul>
+ * <li><b>url</b> - URL where feeds will be pushed (mandatory parameter)</li>
+ * <li><b>batchSize</b> - integer number specifying minimal number of published log records that trigger
+ * processing and pushing ATOM document. If parameter is not set, is not greater than zero or is not a number,
+ * batch size is set to 1.</li>
+ * </ul>
+ * Conversion of log records into ATOM Elements can be tuned up using following parameters. Note that not all
+ * combinations are meaningful, see {@link org.apache.cxf.jaxrs.ext.logging.atom.converter.StandardConverter}
+ * for details:
+ * <ul>
+ * <li><b>output</b> - ATOM Element type pushed out, either "feed" or "entry"; when not specified or invalid
+ * value provided "feed" is used.</li>
+ * <li><b>multiplicity</b> - multiplicity of subelement(entries in feed for output=="feed" or log records in
+ * entry for output=="entry"), either "one" or "many"; when not specified or invalid value provided "one" is
+ * used.</li>
+ * <li><b>format</b> - method of embedding data in entry, either "content" or "extension"; when not specified
+ * or invalid value provided "content" is used.</li>
+ * </ul>
+ * By default delivery is served by WebClientDeliverer which does not support reliability of transport.
+ * Availability of any of this parameters enables retrying of default delivery. Detailed explanation of these
+ * parameter, see {@link org.apache.cxf.jaxrs.ext.logging.atom.deliverer.RetryingDeliverer} class description.
+ * <ul>
+ * <li><b>retry.pause</b> - pausing strategy of delivery retries, either <b>linear</b> or <b>exponential</b>
+ * value (mandatory parameter). If mispelled linear is used.</li>
+ * <li><b>retry.pause.time</b> - pause time (in seconds) between retries. If parameter is not set, pause is
+ * set to 30 seconds.</li>
+ * <li><b>retry.timeout</b> - maximum time (in seconds) retrying will be continued. If not set timeout is not
+ * set (infinite loop of retries).</li>
+ * </ul>
+ * Ultimate control on conversion and delivery is obtained specifying own implementation classes:
+ * <ul>
+ * <li><b>converter</b> - name of class implementing {@link Converter} class replacing default conversion and
+ * its specific parameters ("output", "multiplicity" and "format") are ignored. For classes located in same
+ * package as Converter interface only class name can be given e.g. instead of
+ * "org.apache.cxf.jaxrs.ext.logging.atom.converter.FooBarConverter" one can specify "FooBarConverter".</li>
+ * <li><b>deliverer</b> - name of class implementing {@link Deliverer} class replacing default delivery and
+ * its specific parameters ("retry.Xxx") are ignored. For classes located in same package as Deliverer
+ * interface only class name can be given e.g. instead of
+ * "org.apache.cxf.jaxrs.ext.logging.atom.deliverer.WebClientDeliverer" one can specify
+ * "WebClientDeliverer".</li>
+ * </ul>
+ * Example:
+ *
+ * <pre>
+ * handlers = org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler, java.util.logging.ConsoleHandler
+ * .level = INFO
+ *
+ * # deliver to given URL triggering after each batch of 10 log records
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.url = http://localhost:9080
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.batchSize = 10
+ *
+ * # enable retrying delivery every 10 seconds for 5 minutes
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.retry.pause = linear
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.retry.pause.time = 10
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.retry.timeout = 300
+ *
+ * # output for AtomPub: push entries not feeds, each entry with one log record as "atom:extension"
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.output = entry
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.multiplicity = one
+ * org.apache.cxf.jaxrs.ext.logging.atom.AtomPushHandler.format = extension
+ * ...
+ * </pre>
+ */
+public final class AtomPushHandler extends Handler {
+
+ private AtomPushEngine engine;
+ private boolean lazyConfig;
+
+ /**
+ * Creates handler with configuration taken from properties file.
+ */
+ public AtomPushHandler() {
+ // deferred configuration: configure() called from here would use utilities that attempt to log
+ // and create this handler instance in recursion; configure() will be called on first publish()
+ lazyConfig = true;
+ }
+
+ /**
+ * Creates handler with custom parameters.
+ *
+ * @param batchSize batch size, see {@link AtomPushEngine#getBatchSize()}
+ * @param converter converter transforming logs into ATOM elements
+ * @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()) {
+ return;
+ }
+ LoggingThread.markSilent(true);
+ try {
+ if (lazyConfig) {
+ lazyConfig = false;
+ configure();
+ }
+ LogRecord rec = LogRecord.fromJUL(record);
+ engine.publish(rec);
+ } finally {
+ LoggingThread.markSilent(false);
+ }
+ }
+
+ @Override
+ public synchronized void close() throws SecurityException {
+ engine.shutdown();
+ }
+
+ @Override
+ public synchronized void flush() {
+ // no-op
+ }
+
+ /**
+ * Configuration from properties. Aligned to JUL strategy - properties file is only for simple
+ * configuration: it allows configure one root handler with its parameters. What is even more dummy, JUL
+ * does not allow to iterate over configuration properties to make interpretation automated (e.g. using
+ * commons-beanutils)
+ */
+ private void configure() {
+ LogManager manager = LogManager.getLogManager();
+ String cname = getClass().getName();
+ 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.setRetryPause(manager.getProperty(cname + ".retry.pause"));
+ conf.setRetryPauseTime(manager.getProperty(cname + ".retry.pause.time"));
+ conf.setRetryTimeout(manager.getProperty(cname + ".retry.timeout"));
+ conf.setOutput(manager.getProperty(cname + ".output"));
+ conf.setMultiplicity(manager.getProperty(cname + ".multiplicity"));
+ conf.setFormat(manager.getProperty(cname + ".format"));
+ engine = conf.createEngine();
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/AtomPushHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=886957&r1=886956&r2=886957&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 Thu Dec 3 22:26:58 2009
@@ -1,51 +1,51 @@
-/**
- * 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;
-
-/**
- * Helps disable logging from calls of the same thread. Motivation: log handlers in this package causes other
- * threads (from executor) to start logging (by using JAXB that itself uses JUL) which in turn can be caught
- * by the same handler leading to infinite loop.
- * <p>
- * 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.
- */
-final class LoggingThread {
-
- private static ThreadLocal<LoggingThread> threadLocal = new ThreadLocal<LoggingThread>() {
- @Override
- protected LoggingThread initialValue() {
- return new LoggingThread();
- }
- };
-
- private boolean isSilent;
-
- private LoggingThread() {
- }
-
- public static void markSilent(boolean silent) {
- LoggingThread lt = threadLocal.get();
- lt.isSilent = silent;
- }
-
- public static boolean isSilent() {
- return threadLocal.get().isSilent;
- }
-}
+/**
+ * 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;
+
+/**
+ * Helps disable logging from calls of the same thread. Motivation: log handlers in this package causes other
+ * threads (from executor) to start logging (by using JAXB that itself uses JUL) which in turn can be caught
+ * by the same handler leading to infinite loop.
+ * <p>
+ * 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.
+ */
+final class LoggingThread {
+
+ private static ThreadLocal<LoggingThread> threadLocal = new ThreadLocal<LoggingThread>() {
+ @Override
+ protected LoggingThread initialValue() {
+ return new LoggingThread();
+ }
+ };
+
+ private boolean isSilent;
+
+ private LoggingThread() {
+ }
+
+ public static void markSilent(boolean silent) {
+ LoggingThread lt = threadLocal.get();
+ lt.isSilent = silent;
+ }
+
+ public static boolean isSilent() {
+ return threadLocal.get().isSilent;
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/LoggingThread.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/Converter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/Converter.java?rev=886957&r1=886956&r2=886957&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/Converter.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/Converter.java Thu Dec 3 22:26:58 2009
@@ -1,38 +1,38 @@
-/**
- * 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.converter;
-
-import java.util.List;
-
-import org.apache.abdera.model.Element;
-import org.apache.cxf.jaxrs.ext.logging.LogRecord;
-
-/**
- * Converts batch of log records into one or more ATOM Elements to deliver.
- */
-public interface Converter {
-
- /**
- * Converts given collection.
- *
- * @param records not-null collection of records
- * @return non-empty collection of ATOM Elements that represent log records
- */
- List<? extends Element> convert(List<LogRecord> records);
-}
+/**
+ * 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.converter;
+
+import java.util.List;
+
+import org.apache.abdera.model.Element;
+import org.apache.cxf.jaxrs.ext.logging.LogRecord;
+
+/**
+ * Converts batch of log records into one or more ATOM Elements to deliver.
+ */
+public interface Converter {
+
+ /**
+ * Converts given collection.
+ *
+ * @param records not-null collection of records
+ * @return non-empty collection of ATOM Elements that represent log records
+ */
+ List<? extends Element> convert(List<LogRecord> records);
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/Converter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/Converter.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/StandardConverter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/StandardConverter.java?rev=886957&r1=886956&r2=886957&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/StandardConverter.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/StandardConverter.java Thu Dec 3 22:26:58 2009
@@ -1,315 +1,315 @@
-/**
- * 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.converter;
-
-import java.io.StringWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.namespace.QName;
-
-import org.apache.abdera.Abdera;
-import org.apache.abdera.factory.Factory;
-import org.apache.abdera.model.Content;
-import org.apache.abdera.model.Element;
-import org.apache.abdera.model.Entry;
-import org.apache.abdera.model.ExtensibleElement;
-import org.apache.abdera.model.Feed;
-import org.apache.commons.lang.Validate;
-import org.apache.cxf.jaxrs.ext.logging.LogRecord;
-import org.apache.cxf.jaxrs.ext.logging.LogRecordsList;
-
-/**
- * Converter producing ATOM Feeds on standalone Entries with LogRecords or LogRecordsLists embedded as content
- * or extension. For configuration details see constructor documentation.
- */
-public final class StandardConverter implements Converter {
-
- /** Conversion output */
- public enum Output {
- FEED,
- ENTRY
- }
-
- /** Quantities of entries in feed or logrecords in entry */
- public enum Multiplicity {
- ONE,
- MANY
- }
-
- /** Entity format */
- public enum Format {
- CONTENT,
- EXTENSION
- }
-
- /**
- * Post-processing for feeds/entries properties customization eg setup of dates, titles, author etc.
- */
- public interface Postprocessor {
-
- /** Called after entry creation for given log records. */
- void afterEntry(Entry entry, List<LogRecord> records);
-
- /** Called after feed creation; at this stage feed has associated entries. */
- void afterFeed(Feed feed);
- }
-
- private Factory factory;
- private Marshaller marsh;
- private DateFormat df;
- private Converter worker;
- private Postprocessor postprocessor;
-
- /**
- * Creates configured converter with custom feeds/entries post-processor. Regardless of "format",
- * combination of "output" and "multiplicity" flags can be interpreted as follow:
- * <ul>
- * <li>ENTRY ONE - for each log record one entry is produced, converter returns list of entries</li>
- * <li>ENTRY MANY - list of log records is packed in one entry, converter return one entry.</li>
- * <li>FEED ONE - list of log records is packed in one entry, entry is inserted to feed, converter returns
- * one feed.</li>
- * <li>FEED MANY - for each log record one entry is produced, entries are collected in one feed, converter
- * returns one feed.</li>
- * </ul>
- *
- * @param output whether root elements if Feed or Entry (e.g. for AtomPub).
- * @param multiplicity for output==FEED it is multiplicity of entities in feed for output==ENTITY it is
- * multiplicity of log records in entity.
- * @param format log records embedded as entry content or extension.
- * @param postprocessor custom feeds/entries post-processor.
- */
- public StandardConverter(Output output, Multiplicity multiplicity, Format format,
- Postprocessor postprocessor) {
- Validate.notNull(output, "output is null");
- Validate.notNull(multiplicity, "multiplicity is null");
- Validate.notNull(format, "format is null");
- Validate.notNull(postprocessor, "interceptor is null");
- configure(output, multiplicity, format);
- this.postprocessor = postprocessor;
- df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
- factory = Abdera.getNewFactory();
- try {
- marsh = JAXBContext.newInstance(LogRecordsList.class).createMarshaller();
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Creates configured converter with default post-processing of feeds/entries mandatory properties. See
- * {@link #StandardConverter(Output, Multiplicity, Format, Postprocessor)} for description.
- */
- public StandardConverter(Output output, Multiplicity multiplicity, Format format) {
- this(output, multiplicity, format, new DefaultPostprocessor());
- }
-
- public List<? extends Element> convert(List<LogRecord> records) {
- return worker.convert(records);
- }
-
- private void configure(final Output output, final Multiplicity multiplicity, final Format format) {
- if (output == Output.ENTRY && multiplicity == Multiplicity.ONE) {
- worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
- // produces many entries, each entry with one log record
- List<Element> ret = new ArrayList<Element>();
- for (LogRecord record : records) {
- Entry e;
- if (format == Format.CONTENT) {
- e = createEntry(createContent(record));
- } else {
- e = createEntry(createExtension(record));
- }
- ret.add(e);
- postprocessor.afterEntry(e, Collections.singletonList(record));
- }
- return ret;
- }
- };
- }
- if (output == Output.ENTRY && multiplicity == Multiplicity.MANY) {
- worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
- // produces one entry with list of all log records
- Entry e;
- if (format == Format.CONTENT) {
- e = createEntry(createContent(records));
- } else {
- e = createEntry(createExtension(records));
- }
- postprocessor.afterEntry(e, records);
- return Arrays.asList(e);
- }
- };
- }
- if (output == Output.FEED && multiplicity == Multiplicity.ONE) {
- worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
- // produces one feed with one entry with list of all log records
- Entry e;
- if (format == Format.CONTENT) {
- e = createEntry(createContent(records));
- } else {
- e = createEntry(createExtension(records));
- }
- postprocessor.afterEntry(e, records);
- Feed f = createFeed(e);
- postprocessor.afterFeed(f);
- return Arrays.asList(f);
- }
- };
- }
- if (output == Output.FEED && multiplicity == Multiplicity.MANY) {
- worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
- // produces one feed with many entries, each entry with one log record
- List<Entry> entries = new ArrayList<Entry>();
- for (LogRecord record : records) {
- Entry e;
- if (format == Format.CONTENT) {
- e = createEntry(createContent(record));
- } else {
- e = createEntry(createExtension(record));
- }
- entries.add(e);
- postprocessor.afterEntry(e, Collections.singletonList(record));
- }
- Feed f = createFeed(entries);
- postprocessor.afterFeed(f);
- return Arrays.asList(f);
- }
- };
- }
- if (worker == null) {
- throw new IllegalArgumentException("Unsupported configuration");
- }
- }
-
- private String createContent(LogRecord record) {
- StringWriter writer = new StringWriter();
- try {
- marsh.marshal(record, writer);
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- }
- return writer.toString();
- }
-
- private String createContent(List<LogRecord> records) {
- StringWriter writer = new StringWriter();
- LogRecordsList list = new LogRecordsList();
- list.setLogRecords(records);
- try {
- marsh.marshal(list, writer);
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- }
- return writer.toString();
- }
-
- private ExtensibleElement createExtension(LogRecord record) {
- ExtensibleElement erec = factory.newExtensionElement(qn("logRecord"));
- String date = df.format(record.getEventTimestamp());
- // timezone in date does not have semicolon as XML Date requires
- // e.g we have "2009-11-23T22:03:53.996+0100"
- // instead of "2009-11-23T22:03:53.996+01:00"
- date = date.substring(0, date.length() - 2) + ":" + date.substring(date.length() - 2);
- // forget about single line "addExtension().setText()" since
- // javac failure "org.apache.abdera.model.Element cannot be dereferenced"
- Element e = erec.addExtension(qn("eventTimestamp"));
- e.setText(date);
- e = erec.addExtension(qn("level"));
- e.setText(record.getLevel().toString());
- e = erec.addExtension(qn("loggerName"));
- e.setText(record.getLoggerName());
- e = erec.addExtension(qn("message"));
- e.setText(record.getMessage());
- e = erec.addExtension(qn("threadName"));
- e.setText(record.getThreadName());
- e = erec.addExtension(qn("throwable"));
- e.setText(record.getThrowable());
- return erec;
- }
-
- private QName qn(String name) {
- return new QName("http://cxf.apache.org/jaxrs/log", name, "log");
- }
-
- private ExtensibleElement createExtension(List<LogRecord> records) {
- ExtensibleElement list = factory.newExtensionElement(qn("logRecordsList"));
- for (LogRecord rec : records) {
- list.addExtension(createExtension(rec));
- }
- return list;
- }
-
- private Entry createEntry(String content) {
- Entry entry = factory.newEntry();
- entry.setContent(content, Content.Type.XML);
- return entry;
- }
-
- private Entry createEntry(ExtensibleElement ext) {
- Entry entry = factory.newEntry();
- entry.addExtension(ext);
- return entry;
- }
-
- private Feed createFeed(Entry entry) {
- Feed feed = factory.newFeed();
- feed.addEntry(entry);
- return feed;
- }
-
- private Feed createFeed(List<Entry> entries) {
- Feed feed = factory.newFeed();
- for (Entry entry : entries) {
- feed.addEntry(entry);
- }
- return feed;
- }
-
- private static class DefaultPostprocessor implements Postprocessor {
- public void afterEntry(Entry entry, List<LogRecord> records) {
- // required fields (see RFC 4287)
- entry.setId("uuid:" + UUID.randomUUID().toString());
- entry.addAuthor("CXF");
- entry.setTitle(String.format("Entry with %d log record(s)", records.size()));
- entry.setUpdated(new Date());
- }
-
- public void afterFeed(Feed feed) {
- // required fields (see RFC 4287)
- feed.setId("uuid:" + UUID.randomUUID().toString());
- feed.addAuthor("CXF");
- feed.setTitle(String.format("Feed with %d entry(ies)", feed.getEntries().size()));
- feed.setUpdated(new Date());
- }
- }
-}
+/**
+ * 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.converter;
+
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.ExtensibleElement;
+import org.apache.abdera.model.Feed;
+import org.apache.commons.lang.Validate;
+import org.apache.cxf.jaxrs.ext.logging.LogRecord;
+import org.apache.cxf.jaxrs.ext.logging.LogRecordsList;
+
+/**
+ * Converter producing ATOM Feeds on standalone Entries with LogRecords or LogRecordsLists embedded as content
+ * or extension. For configuration details see constructor documentation.
+ */
+public final class StandardConverter implements Converter {
+
+ /** Conversion output */
+ public enum Output {
+ FEED,
+ ENTRY
+ }
+
+ /** Quantities of entries in feed or logrecords in entry */
+ public enum Multiplicity {
+ ONE,
+ MANY
+ }
+
+ /** Entity format */
+ public enum Format {
+ CONTENT,
+ EXTENSION
+ }
+
+ /**
+ * Post-processing for feeds/entries properties customization eg setup of dates, titles, author etc.
+ */
+ public interface Postprocessor {
+
+ /** Called after entry creation for given log records. */
+ void afterEntry(Entry entry, List<LogRecord> records);
+
+ /** Called after feed creation; at this stage feed has associated entries. */
+ void afterFeed(Feed feed);
+ }
+
+ private Factory factory;
+ private Marshaller marsh;
+ private DateFormat df;
+ private Converter worker;
+ private Postprocessor postprocessor;
+
+ /**
+ * Creates configured converter with custom feeds/entries post-processor. Regardless of "format",
+ * combination of "output" and "multiplicity" flags can be interpreted as follow:
+ * <ul>
+ * <li>ENTRY ONE - for each log record one entry is produced, converter returns list of entries</li>
+ * <li>ENTRY MANY - list of log records is packed in one entry, converter return one entry.</li>
+ * <li>FEED ONE - list of log records is packed in one entry, entry is inserted to feed, converter returns
+ * one feed.</li>
+ * <li>FEED MANY - for each log record one entry is produced, entries are collected in one feed, converter
+ * returns one feed.</li>
+ * </ul>
+ *
+ * @param output whether root elements if Feed or Entry (e.g. for AtomPub).
+ * @param multiplicity for output==FEED it is multiplicity of entities in feed for output==ENTITY it is
+ * multiplicity of log records in entity.
+ * @param format log records embedded as entry content or extension.
+ * @param postprocessor custom feeds/entries post-processor.
+ */
+ public StandardConverter(Output output, Multiplicity multiplicity, Format format,
+ Postprocessor postprocessor) {
+ Validate.notNull(output, "output is null");
+ Validate.notNull(multiplicity, "multiplicity is null");
+ Validate.notNull(format, "format is null");
+ Validate.notNull(postprocessor, "interceptor is null");
+ configure(output, multiplicity, format);
+ this.postprocessor = postprocessor;
+ df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ factory = Abdera.getNewFactory();
+ try {
+ marsh = JAXBContext.newInstance(LogRecordsList.class).createMarshaller();
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Creates configured converter with default post-processing of feeds/entries mandatory properties. See
+ * {@link #StandardConverter(Output, Multiplicity, Format, Postprocessor)} for description.
+ */
+ public StandardConverter(Output output, Multiplicity multiplicity, Format format) {
+ this(output, multiplicity, format, new DefaultPostprocessor());
+ }
+
+ public List<? extends Element> convert(List<LogRecord> records) {
+ return worker.convert(records);
+ }
+
+ private void configure(final Output output, final Multiplicity multiplicity, final Format format) {
+ if (output == Output.ENTRY && multiplicity == Multiplicity.ONE) {
+ worker = new Converter() {
+ public List<? extends Element> convert(List<LogRecord> records) {
+ // produces many entries, each entry with one log record
+ List<Element> ret = new ArrayList<Element>();
+ for (LogRecord record : records) {
+ Entry e;
+ if (format == Format.CONTENT) {
+ e = createEntry(createContent(record));
+ } else {
+ e = createEntry(createExtension(record));
+ }
+ ret.add(e);
+ postprocessor.afterEntry(e, Collections.singletonList(record));
+ }
+ return ret;
+ }
+ };
+ }
+ if (output == Output.ENTRY && multiplicity == Multiplicity.MANY) {
+ worker = new Converter() {
+ public List<? extends Element> convert(List<LogRecord> records) {
+ // produces one entry with list of all log records
+ Entry e;
+ if (format == Format.CONTENT) {
+ e = createEntry(createContent(records));
+ } else {
+ e = createEntry(createExtension(records));
+ }
+ postprocessor.afterEntry(e, records);
+ return Arrays.asList(e);
+ }
+ };
+ }
+ if (output == Output.FEED && multiplicity == Multiplicity.ONE) {
+ worker = new Converter() {
+ public List<? extends Element> convert(List<LogRecord> records) {
+ // produces one feed with one entry with list of all log records
+ Entry e;
+ if (format == Format.CONTENT) {
+ e = createEntry(createContent(records));
+ } else {
+ e = createEntry(createExtension(records));
+ }
+ postprocessor.afterEntry(e, records);
+ Feed f = createFeed(e);
+ postprocessor.afterFeed(f);
+ return Arrays.asList(f);
+ }
+ };
+ }
+ if (output == Output.FEED && multiplicity == Multiplicity.MANY) {
+ worker = new Converter() {
+ public List<? extends Element> convert(List<LogRecord> records) {
+ // produces one feed with many entries, each entry with one log record
+ List<Entry> entries = new ArrayList<Entry>();
+ for (LogRecord record : records) {
+ Entry e;
+ if (format == Format.CONTENT) {
+ e = createEntry(createContent(record));
+ } else {
+ e = createEntry(createExtension(record));
+ }
+ entries.add(e);
+ postprocessor.afterEntry(e, Collections.singletonList(record));
+ }
+ Feed f = createFeed(entries);
+ postprocessor.afterFeed(f);
+ return Arrays.asList(f);
+ }
+ };
+ }
+ if (worker == null) {
+ throw new IllegalArgumentException("Unsupported configuration");
+ }
+ }
+
+ private String createContent(LogRecord record) {
+ StringWriter writer = new StringWriter();
+ try {
+ marsh.marshal(record, writer);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ return writer.toString();
+ }
+
+ private String createContent(List<LogRecord> records) {
+ StringWriter writer = new StringWriter();
+ LogRecordsList list = new LogRecordsList();
+ list.setLogRecords(records);
+ try {
+ marsh.marshal(list, writer);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ return writer.toString();
+ }
+
+ private ExtensibleElement createExtension(LogRecord record) {
+ ExtensibleElement erec = factory.newExtensionElement(qn("logRecord"));
+ String date = df.format(record.getEventTimestamp());
+ // timezone in date does not have semicolon as XML Date requires
+ // e.g we have "2009-11-23T22:03:53.996+0100"
+ // instead of "2009-11-23T22:03:53.996+01:00"
+ date = date.substring(0, date.length() - 2) + ":" + date.substring(date.length() - 2);
+ // forget about single line "addExtension().setText()" since
+ // javac failure "org.apache.abdera.model.Element cannot be dereferenced"
+ Element e = erec.addExtension(qn("eventTimestamp"));
+ e.setText(date);
+ e = erec.addExtension(qn("level"));
+ e.setText(record.getLevel().toString());
+ e = erec.addExtension(qn("loggerName"));
+ e.setText(record.getLoggerName());
+ e = erec.addExtension(qn("message"));
+ e.setText(record.getMessage());
+ e = erec.addExtension(qn("threadName"));
+ e.setText(record.getThreadName());
+ e = erec.addExtension(qn("throwable"));
+ e.setText(record.getThrowable());
+ return erec;
+ }
+
+ private QName qn(String name) {
+ return new QName("http://cxf.apache.org/jaxrs/log", name, "log");
+ }
+
+ private ExtensibleElement createExtension(List<LogRecord> records) {
+ ExtensibleElement list = factory.newExtensionElement(qn("logRecordsList"));
+ for (LogRecord rec : records) {
+ list.addExtension(createExtension(rec));
+ }
+ return list;
+ }
+
+ private Entry createEntry(String content) {
+ Entry entry = factory.newEntry();
+ entry.setContent(content, Content.Type.XML);
+ return entry;
+ }
+
+ private Entry createEntry(ExtensibleElement ext) {
+ Entry entry = factory.newEntry();
+ entry.addExtension(ext);
+ return entry;
+ }
+
+ private Feed createFeed(Entry entry) {
+ Feed feed = factory.newFeed();
+ feed.addEntry(entry);
+ return feed;
+ }
+
+ private Feed createFeed(List<Entry> entries) {
+ Feed feed = factory.newFeed();
+ for (Entry entry : entries) {
+ feed.addEntry(entry);
+ }
+ return feed;
+ }
+
+ private static class DefaultPostprocessor implements Postprocessor {
+ public void afterEntry(Entry entry, List<LogRecord> records) {
+ // required fields (see RFC 4287)
+ entry.setId("uuid:" + UUID.randomUUID().toString());
+ entry.addAuthor("CXF");
+ entry.setTitle(String.format("Entry with %d log record(s)", records.size()));
+ entry.setUpdated(new Date());
+ }
+
+ public void afterFeed(Feed feed) {
+ // required fields (see RFC 4287)
+ feed.setId("uuid:" + UUID.randomUUID().toString());
+ feed.addAuthor("CXF");
+ feed.setTitle(String.format("Feed with %d entry(ies)", feed.getEntries().size()));
+ feed.setUpdated(new Date());
+ }
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/StandardConverter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converter/StandardConverter.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java?rev=886957&r1=886956&r2=886957&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java Thu Dec 3 22:26:58 2009
@@ -1,36 +1,36 @@
-/**
- * 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.deliverer;
-
-import org.apache.abdera.model.Element;
-
-/**
- * ATOM element deliverer. Represents transport strategy e.g. using
- * {@link org.apache.cxf.jaxrs.client.WebClient}, SOAP reliable messaging etc.
- */
-public interface Deliverer {
-
- /**
- * Delivers ATOM element.
- *
- * @param element element to deliver.
- * @return true if delivery successful, false otherwise.
- */
- boolean deliver(Element element) throws InterruptedException;
-}
+/**
+ * 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.deliverer;
+
+import org.apache.abdera.model.Element;
+
+/**
+ * ATOM element deliverer. Represents transport strategy e.g. using
+ * {@link org.apache.cxf.jaxrs.client.WebClient}, SOAP reliable messaging etc.
+ */
+public interface Deliverer {
+
+ /**
+ * Delivers ATOM element.
+ *
+ * @param element element to deliver.
+ * @return true if delivery successful, false otherwise.
+ */
+ boolean deliver(Element element) throws InterruptedException;
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/FireAndForgetDeliverer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/FireAndForgetDeliverer.java?rev=886957&r1=886956&r2=886957&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/FireAndForgetDeliverer.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/FireAndForgetDeliverer.java Thu Dec 3 22:26:58 2009
@@ -1,41 +1,41 @@
-/**
- * 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.deliverer;
-
-import org.apache.abdera.model.Element;
-import org.apache.commons.lang.Validate;
-
-/**
- * Fires delivery of wrapper deliverer and forgets about status always assuming success. Fire-and-forget works
- * only for regular flow, runtime and interrupted exceptions are not handled.
- */
-public final class FireAndForgetDeliverer implements Deliverer {
-
- private Deliverer deliverer;
-
- public FireAndForgetDeliverer(Deliverer worker) {
- Validate.notNull(worker, "worker is null");
- deliverer = worker;
- }
-
- public boolean deliver(Element element) throws InterruptedException {
- deliverer.deliver(element);
- return true;
- }
-}
+/**
+ * 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.deliverer;
+
+import org.apache.abdera.model.Element;
+import org.apache.commons.lang.Validate;
+
+/**
+ * Fires delivery of wrapper deliverer and forgets about status always assuming success. Fire-and-forget works
+ * only for regular flow, runtime and interrupted exceptions are not handled.
+ */
+public final class FireAndForgetDeliverer implements Deliverer {
+
+ private Deliverer deliverer;
+
+ public FireAndForgetDeliverer(Deliverer worker) {
+ Validate.notNull(worker, "worker is null");
+ deliverer = worker;
+ }
+
+ public boolean deliver(Element element) throws InterruptedException {
+ deliverer.deliver(element);
+ return true;
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/FireAndForgetDeliverer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/FireAndForgetDeliverer.java
------------------------------------------------------------------------------
svn:keywords = Rev Date