You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/12/18 13:23:54 UTC
svn commit: r892237 - 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/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/converte...
Author: sergeyb
Date: Fri Dec 18 12:23:54 2009
New Revision: 892237
URL: http://svn.apache.org/viewvc?rev=892237&view=rev
Log:
JAXRS : some Atom push logging updates
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java (with props)
Removed:
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/deliverer/FireAndForgetDeliverer.java
Modified:
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/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/AtomPushEngineConfigurator.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/converter/StandardConverter.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/Deliverer.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/RetryingDeliverer.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/WebClientDeliverer.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/package-info.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushTest.java
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml
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=892237&r1=892236&r2=892237&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 Dec 18 12:23:54 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(namespace = "http://cxf.apache.org/jaxrs/log")
+@XmlRootElement(namespace = "http://cxf.apache.org/log")
public class LogRecord {
private Date eventTimestamp = new Date();
@@ -77,7 +77,7 @@
return record;
}
- @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
+ @XmlElement(namespace = "http://cxf.apache.org/log")
public Date getEventTimestamp() {
return eventTimestamp;
}
@@ -87,7 +87,7 @@
this.eventTimestamp = eventTimestamp;
}
- @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
+ @XmlElement(namespace = "http://cxf.apache.org/log")
public LogLevel getLevel() {
return level;
}
@@ -100,7 +100,7 @@
/**
* Formatted message with parameters filled in.
*/
- @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
+ @XmlElement(namespace = "http://cxf.apache.org/log")
public String getMessage() {
return message;
}
@@ -110,7 +110,7 @@
this.message = renderedMessage;
}
- @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
+ @XmlElement(namespace = "http://cxf.apache.org/log")
public String getLoggerName() {
return loggerName;
}
@@ -120,7 +120,7 @@
this.loggerName = loggerName;
}
- @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
+ @XmlElement(namespace = "http://cxf.apache.org/log")
public String getThreadName() {
return threadName;
}
@@ -133,7 +133,7 @@
/**
* Full stack trace of {@link Throwable} associated with log record.
*/
- @XmlElement(namespace = "http://cxf.apache.org/jaxrs/log")
+ @XmlElement(namespace = "http://cxf.apache.org/log")
public String getThrowable() {
return throwable;
}
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java?rev=892237&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java Fri Dec 18 12:23:54 2009
@@ -0,0 +1,65 @@
+/**
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang.Validate;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+/**
+ * List of {@link LogRecord}s. Necessary wrapper for {@link List} used in JAXB context.
+ */
+@XmlRootElement(namespace = "http://cxf.apache.org/log")
+public class LogRecords {
+
+ private List<LogRecord> logRecords = new ArrayList<LogRecord>();
+
+ @XmlElement(name = "logRecord", namespace = "http://cxf.apache.org/log")
+ public List<LogRecord> getLogRecords() {
+ return logRecords;
+ }
+
+ public void setLogRecords(List<LogRecord> logRecords) {
+ Validate.notNull(logRecords, "logRecords is null");
+ this.logRecords = logRecords;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return EqualsBuilder.reflectionEquals(obj, this);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/LogRecords.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=892237&r1=892236&r2=892237&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 Dec 18 12:23:54 2009
@@ -189,6 +189,15 @@
Validate.notNull(batchSize, "batchSize is null");
conf.setBatchSize(batchSize);
}
+
+ /**
+ * Batch cleanup time in minutes
+ */
+ public void setBatchCleanupTime(String batchCleanupTime) {
+ checkInit();
+ Validate.notNull(batchCleanupTime, "batchCleanup is null");
+ conf.setBatchCleanupTime(batchCleanupTime);
+ }
/**
* Retry pause calculation strategy, either "linear" or "exponential".
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=892237&r1=892236&r2=892237&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 Dec 18 12:23:54 2009
@@ -19,7 +19,10 @@
package org.apache.cxf.jaxrs.ext.logging.atom;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -51,9 +54,11 @@
private List<LogRecord> queue = new ArrayList<LogRecord>();
private ExecutorService executor = Executors.newSingleThreadExecutor();
private int batchSize = 1;
+ private int batchTime;
private Converter converter;
private Deliverer deliverer;
-
+ private Timer timer;
+
/**
* Put record to publishing queue. Engine accepts published records only if is in proper state - is
* properly configured (has deliverer and converter registered) and is not shot down; otherwise calls to
@@ -64,19 +69,33 @@
public synchronized void publish(LogRecord record) {
Validate.notNull(record, "record is null");
if (isValid()) {
+ if (batchSize > 1 && batchTime > 0 && timer == null) {
+ createTimerTask(batchTime * 60 * 1000);
+ }
queue.add(record);
if (queue.size() >= batchSize) {
- publishBatch(queue);
- queue = new ArrayList<LogRecord>();
+ publishAndReset();
}
+ } else {
+ handleUndeliveredRecords(Collections.singletonList(record),
+ deliverer == null ? "" : deliverer.getEndpointAddress());
}
}
+
+ protected synchronized void publishAndReset() {
+ publishBatch(queue, deliverer, converter);
+ queue = new ArrayList<LogRecord>();
+ }
/**
* Shuts engine down.
*/
public synchronized void shutdown() {
- executor.shutdownNow();
+ cancelTimerTask();
+ if (isValid() && queue.size() > 0) {
+ publishAndReset();
+ }
+ executor.shutdown();
}
private boolean isValid() {
@@ -96,25 +115,36 @@
return true;
}
- private void publishBatch(final List<LogRecord> batch) {
+ private void publishBatch(final List<LogRecord> batch,
+ final Deliverer d,
+ final Converter c) {
executor.execute(new Runnable() {
public void run() {
try {
LoggingThread.markSilent(true);
- // syncing for safe converter/deliverer on the fly replacement
- synchronized (this) {
- // TODO diagnostic output here: System.out.println(element.toString());
- List<? extends Element> elements = converter.convert(batch);
- for (Element element : elements) {
- if (!deliverer.deliver(element)) {
- System.err.println("Delivery failed, shutting engine down");
- executor.shutdownNow();
- break;
+ List<? extends Element> elements = c.convert(batch);
+ for (int i = 0; i < elements.size(); i++) {
+ Element element = elements.get(i);
+ if (!d.deliver(element)) {
+ System.err.println("Delivery to " + d.getEndpointAddress()
+ + " failed, shutting engine down");
+ List<LogRecord> undelivered = null;
+ if (i == 0) {
+ undelivered = batch;
+ } else {
+ int index = (batch.size() / elements.size()) * i;
+ // should not happen but just in case :-)
+ if (index < batch.size()) {
+ undelivered = batch.subList(index, batch.size());
+ }
}
+ handleUndeliveredRecords(undelivered, d.getEndpointAddress());
+ shutdown();
+ break;
}
}
} catch (InterruptedException e) {
- // no action on executor.shutdownNow();
+ // no action
} finally {
LoggingThread.markSilent(false);
}
@@ -122,6 +152,14 @@
});
}
+ protected void handleUndeliveredRecords(List<LogRecord> records, String address) {
+ // TODO : save them to some transient storage perhaps ?
+ System.err.println("The following records have been undelivered to " + address + " : ");
+ for (LogRecord r : records) {
+ System.err.println(r.toString());
+ }
+ }
+
public int getBatchSize() {
return batchSize;
}
@@ -130,8 +168,36 @@
Validate.isTrue(batchSize > 0, "batch size is not greater than zero");
this.batchSize = batchSize;
}
+
+ public void setBatchTime(int batchTime) {
+ this.batchTime = batchTime;
+ }
- public Converter getConverter() {
+ /**
+ * Creates a timer task which will periodically flush the batch queue
+ * thus ensuring log records won't become too 'stale'.
+ * Ex, if we have a batch size 10 and only WARN records need to be delivered
+ * then without the periodic cleanup the consumers may not get prompt notifications
+ *
+ * @param timeout
+ */
+ protected void createTimerTask(long timeout) {
+ timer = new Timer();
+ timer.schedule(new TimerTask() {
+ public void run() {
+ publishAndReset();
+ }
+ }, timeout);
+ }
+
+ protected void cancelTimerTask() {
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ }
+
+ public synchronized Converter getConverter() {
return converter;
}
@@ -140,7 +206,7 @@
this.converter = converter;
}
- public Deliverer getDeliverer() {
+ public synchronized Deliverer getDeliverer() {
return deliverer;
}
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=892237&r1=892236&r2=892237&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 Fri Dec 18 12:23:54 2009
@@ -41,6 +41,7 @@
private String delivererClass;
private String converterClass;
private String batchSize;
+ private String batchCleanupTime;
private String delivererUrl;
private String retryTimeout;
private String retryPause;
@@ -65,6 +66,10 @@
this.retryPauseTime = retryPauseTime;
}
+ public void setBatchCleanupTime(String cleanupTime) {
+ this.batchCleanupTime = cleanupTime;
+ }
+
public void setBatchSize(String batchSize) {
this.batchSize = batchSize;
}
@@ -101,6 +106,7 @@
Deliverer d = deliverer;
Converter c = converter;
int batch = parseInt(batchSize, 1, 1);
+ int batchTime = parseInt(batchCleanupTime, 0);
if (d == null) {
if (delivererUrl != null) {
if (delivererClass != null) {
@@ -118,9 +124,15 @@
c = createConverter(converterClass);
} else {
Output out = parseEnum(output, Output.FEED);
- Multiplicity mul = parseEnum(multiplicity, Multiplicity.ONE);
+ Multiplicity defaultMul = out == Output.FEED ? Multiplicity.MANY
+ : batch > 1 ? Multiplicity.MANY : Multiplicity.ONE;
+ Multiplicity mul = parseEnum(multiplicity, defaultMul);
Format form = parseEnum(format, Format.CONTENT);
- c = new StandardConverter(out, mul, form);
+ if (out == Output.FEED) {
+ c = new StandardConverter(out, mul, form);
+ } else {
+ c = new StandardConverter(out, mul, form);
+ }
if (retryPause != null) {
int timeout = parseInt(retryTimeout, 0, 0);
int pause = parseInt(retryPauseTime, 1, 30);
@@ -133,6 +145,7 @@
engine.setDeliverer(d);
engine.setConverter(c);
engine.setBatchSize(batch);
+ engine.setBatchTime(batchTime);
return engine;
}
@@ -145,6 +158,7 @@
}
}
+ @SuppressWarnings("unchecked")
private Converter createConverter(String clazz) {
try {
Constructor<Converter> ctor = loadClass(clazz, Converter.class).getConstructor();
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=892237&r1=892236&r2=892237&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 Dec 18 12:23:54 2009
@@ -173,6 +173,7 @@
conf.setDelivererClass(manager.getProperty(cname + ".deliverer"));
conf.setConverterClass(manager.getProperty(cname + ".converter"));
conf.setBatchSize(manager.getProperty(cname + ".batchSize"));
+ conf.setBatchCleanupTime(manager.getProperty(cname + ".batchCleanupTime"));
conf.setRetryPause(manager.getProperty(cname + ".retry.pause"));
conf.setRetryPauseTime(manager.getProperty(cname + ".retry.pause.time"));
conf.setRetryTimeout(manager.getProperty(cname + ".retry.timeout"));
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=892237&r1=892236&r2=892237&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 Fri Dec 18 12:23:54 2009
@@ -31,7 +31,6 @@
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;
@@ -45,7 +44,7 @@
import org.apache.cxf.jaxrs.ext.atom.AbstractEntryBuilder;
import org.apache.cxf.jaxrs.ext.atom.AbstractFeedBuilder;
import org.apache.cxf.jaxrs.ext.logging.LogRecord;
-import org.apache.cxf.jaxrs.ext.logging.LogRecordsList;
+import org.apache.cxf.jaxrs.ext.logging.LogRecords;
/**
* Converter producing ATOM Feeds on standalone Entries with LogRecords or LogRecordsLists embedded as content
@@ -72,10 +71,11 @@
}
private Factory factory;
- private Marshaller marsh;
+ private JAXBContext context;
private DateFormat df;
private Converter worker;
- private Postprocessor postprocessor;
+ private AbstractFeedBuilder<List<LogRecord>> feedBuilder;
+ private AbstractEntryBuilder<List<LogRecord>> entryBuilder;
/**
* Creates configured converter with default post-processing of feeds/entries mandatory properties.
@@ -95,7 +95,7 @@
* @param format log records embedded as entry content or extension.
*/
public StandardConverter(Output output, Multiplicity multiplicity, Format format) {
- this(output, multiplicity, format, new DefaultPostprocessor());
+ this(output, multiplicity, format, null, null);
}
/**
@@ -105,21 +105,17 @@
public StandardConverter(Output output, Multiplicity multiplicity, Format format,
AbstractFeedBuilder<List<LogRecord>> feedBuilder,
AbstractEntryBuilder<List<LogRecord>> entryBuilder) {
- this(output, multiplicity, format, new BuilderPostprocessor(feedBuilder, entryBuilder));
- }
-
- private 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");
+ this.feedBuilder = feedBuilder;
+ this.entryBuilder = entryBuilder;
+
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();
+ context = JAXBContext.newInstance(LogRecords.class, LogRecord.class);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
@@ -132,73 +128,32 @@
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;
+ public List<Entry> convert(List<LogRecord> records) {
+ return createEntries(format, records);
}
};
}
if (output == Output.ENTRY && multiplicity == Multiplicity.MANY) {
worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
+ public List<Entry> 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);
+ return Arrays.asList(createEntryFromList(format, records));
}
};
}
if (output == Output.FEED && multiplicity == Multiplicity.ONE) {
worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
+ public List<Feed> 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, records);
- return Arrays.asList(f);
+ return Arrays.asList(createFeedWithSingleEntry(format, records));
}
};
}
if (output == Output.FEED && multiplicity == Multiplicity.MANY) {
worker = new Converter() {
- public List<? extends Element> convert(List<LogRecord> records) {
+ public List<Feed> 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, records);
- return Arrays.asList(f);
+ return Arrays.asList(createFeed(format, records));
}
};
}
@@ -207,10 +162,38 @@
}
}
+ private List<Entry> createEntries(Format format, List<LogRecord> records) {
+ List<Entry> entries = new ArrayList<Entry>();
+ for (LogRecord record : records) {
+ entries.add(createEntryFromRecord(format, record));
+ }
+ return entries;
+ }
+
+ private Entry createEntryFromList(Format format, List<LogRecord> records) {
+ Entry e = createEntry(records);
+ if (format == Format.CONTENT) {
+ setEntryContent(e, createContent(records));
+ } else {
+ setEntryContent(e, createExtension(records));
+ }
+ return e;
+ }
+
+ private Entry createEntryFromRecord(Format format, LogRecord record) {
+ Entry e = createEntry(Collections.singletonList(record));
+ if (format == Format.CONTENT) {
+ setEntryContent(e, createContent(record));
+ } else {
+ setEntryContent(e, createExtension(record));
+ }
+ return e;
+ }
+
private String createContent(LogRecord record) {
StringWriter writer = new StringWriter();
try {
- marsh.marshal(record, writer);
+ context.createMarshaller().marshal(record, writer);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
@@ -219,10 +202,10 @@
private String createContent(List<LogRecord> records) {
StringWriter writer = new StringWriter();
- LogRecordsList list = new LogRecordsList();
+ LogRecords list = new LogRecords();
list.setLogRecords(records);
try {
- marsh.marshal(list, writer);
+ context.createMarshaller().marshal(list, writer);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
@@ -254,86 +237,80 @@
}
private QName qn(String name) {
- return new QName("http://cxf.apache.org/jaxrs/log", name, "log");
+ return new QName("http://cxf.apache.org/log", name, "log");
}
private ExtensibleElement createExtension(List<LogRecord> records) {
- ExtensibleElement list = factory.newExtensionElement(qn("logRecordsList"));
+ ExtensibleElement list = factory.newExtensionElement(qn("logRecords"));
for (LogRecord rec : records) {
list.addExtension(createExtension(rec));
}
return list;
}
- private Entry createEntry(String content) {
+ private Entry createEntry(List<LogRecord> records) {
Entry entry = factory.newEntry();
- entry.setContent(content, Content.Type.XML);
+ setDefaultEntryProperties(entry, records);
+
return entry;
}
+
+ private void setEntryContent(Entry e, String content) {
+ e.setContent(content, Content.Type.XML);
+ }
- private Entry createEntry(ExtensibleElement ext) {
- Entry entry = factory.newEntry();
- entry.addExtension(ext);
- return entry;
+ private void setEntryContent(Entry e, ExtensibleElement ext) {
+ e.addExtension(ext);
}
- private Feed createFeed(Entry entry) {
+ private Feed createFeedWithSingleEntry(Format format, List<LogRecord> records) {
+
Feed feed = factory.newFeed();
- feed.addEntry(entry);
+ feed.addEntry(createEntryFromList(format, records));
+ setDefaultFeedProperties(feed, records);
return feed;
}
-
- private Feed createFeed(List<Entry> entries) {
+
+ private Feed createFeed(Format format, List<LogRecord> records) {
+
Feed feed = factory.newFeed();
+ List<Entry> entries = createEntries(format, records);
for (Entry entry : entries) {
feed.addEntry(entry);
}
+ setDefaultFeedProperties(feed, records);
return feed;
}
- /**
- * Post-processing for feeds/entries properties customization eg setup of dates, titles, author etc.
- */
- private 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, List<LogRecord> records);
- }
-
- 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, List<LogRecord> records) {
- // required fields (see RFC 4287)
+ protected void setDefaultFeedProperties(Feed feed, List<LogRecord> records) {
+ if (feedBuilder != null) {
+ feed.setId(feedBuilder.getId(records));
+ feed.addAuthor(feedBuilder.getAuthor(records));
+ feed.setTitle(feedBuilder.getTitle(records));
+ feed.setUpdated(feedBuilder.getUpdated(records));
+ feed.setBaseUri(feedBuilder.getBaseUri(records));
+ List<String> categories = feedBuilder.getCategories(records);
+ if (categories != null) {
+ for (String category : categories) {
+ feed.addCategory(category);
+ }
+ }
+ Map<String, String> links = feedBuilder.getLinks(records);
+ if (links != null) {
+ for (java.util.Map.Entry<String, String> mapEntry : links.entrySet()) {
+ feed.addLink(mapEntry.getKey(), mapEntry.getValue());
+ }
+ }
+ } else {
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());
}
}
-
- private static class BuilderPostprocessor implements Postprocessor {
- private AbstractFeedBuilder<List<LogRecord>> feedBuilder;
- private AbstractEntryBuilder<List<LogRecord>> entryBuilder;
-
- public BuilderPostprocessor(AbstractFeedBuilder<List<LogRecord>> feedBuilder,
- AbstractEntryBuilder<List<LogRecord>> entryBuilder) {
- Validate.notNull(feedBuilder, "feedBuilder is null");
- Validate.notNull(entryBuilder, "entryBuilder is null");
- this.feedBuilder = feedBuilder;
- this.entryBuilder = entryBuilder;
- }
-
- public void afterEntry(Entry entry, List<LogRecord> records) {
+
+ protected void setDefaultEntryProperties(Entry entry, List<LogRecord> records) {
+ if (entryBuilder != null) {
entry.setId(entryBuilder.getId(records));
entry.addAuthor(entryBuilder.getAuthor(records));
entry.setTitle(entryBuilder.getTitle(records));
@@ -353,26 +330,13 @@
}
entry.setPublished(entryBuilder.getPublished(records));
entry.setSummary(entryBuilder.getSummary(records));
- }
-
- public void afterFeed(Feed feed, List<LogRecord> records) {
- feed.setId(feedBuilder.getId(records));
- feed.addAuthor(feedBuilder.getAuthor(records));
- feed.setTitle(feedBuilder.getTitle(records));
- feed.setUpdated(feedBuilder.getUpdated(records));
- feed.setBaseUri(feedBuilder.getBaseUri(records));
- List<String> categories = feedBuilder.getCategories(records);
- if (categories != null) {
- for (String category : categories) {
- feed.addCategory(category);
- }
- }
- Map<String, String> links = feedBuilder.getLinks(records);
- if (links != null) {
- for (java.util.Map.Entry<String, String> mapEntry : links.entrySet()) {
- feed.addLink(mapEntry.getKey(), mapEntry.getValue());
- }
- }
+ } else {
+ 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());
}
}
+
}
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=892237&r1=892236&r2=892237&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 Fri Dec 18 12:23:54 2009
@@ -33,4 +33,10 @@
* @return true if delivery successful, false otherwise.
*/
boolean deliver(Element element) throws InterruptedException;
+
+ /**
+ * Returns the address of the remote endpoint this deliverer send elements to
+ * @return
+ */
+ String getEndpointAddress();
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/RetryingDeliverer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/RetryingDeliverer.java?rev=892237&r1=892236&r2=892237&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/RetryingDeliverer.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/RetryingDeliverer.java Fri Dec 18 12:23:54 2009
@@ -136,4 +136,8 @@
}
}
+ public String getEndpointAddress() {
+ return deliverer.getEndpointAddress();
+ }
+
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/WebClientDeliverer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/WebClientDeliverer.java?rev=892237&r1=892236&r2=892237&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/WebClientDeliverer.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/logging/atom/deliverer/WebClientDeliverer.java Fri Dec 18 12:23:54 2009
@@ -24,6 +24,7 @@
import javax.ws.rs.core.Response;
import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Feed;
import org.apache.commons.lang.Validate;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.provider.AtomEntryProvider;
@@ -40,7 +41,6 @@
Validate.notEmpty(deliveryAddress, "deliveryAddress is empty or null");
List<?> providers = Arrays.asList(new AtomFeedProvider(), new AtomEntryProvider());
wc = WebClient.create(deliveryAddress, providers);
- wc.type("application/atom+xml");
}
public WebClientDeliverer(WebClient wc) {
@@ -49,8 +49,14 @@
}
public boolean deliver(Element element) {
+ String type = element instanceof Feed ? "application/atom+xml" : "application/atom+xml;type=entry";
+ wc.type(type);
Response res = wc.post(element);
int status = res.getStatus();
return status >= 200 && status <= 299;
}
+
+ public String getEndpointAddress() {
+ return wc.getBaseURI().toString();
+ }
}
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=892237&r1=892236&r2=892237&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 Dec 18 12:23:54 2009
@@ -18,14 +18,14 @@
*/
/**
- * JAX-RS specific logging support. Based on <tt>java.util.logging</tt> (JUL)
+ * CXF specific logging support. Based on <tt>java.util.logging</tt> (JUL)
* with use of different logging frameworks factored out; assumes that client
* with source code logging to other systems, like Log4J, can bridge
* 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")
+ @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://cxf.apache.org/log", prefix = "log")
})
package org.apache.cxf.jaxrs.ext.logging;
Modified: 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=892237&r1=892236&r2=892237&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushSpringTest.java Fri Dec 18 12:23:54 2009
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.systest.jaxrs;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
@@ -27,11 +28,16 @@
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
+import javax.xml.bind.JAXBContext;
+import javax.xml.namespace.QName;
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.cxf.common.logging.LogUtils;
import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.ext.logging.LogRecords;
import org.apache.cxf.testutil.common.AbstractClientServerTestBase;
import org.junit.Before;
@@ -41,8 +47,12 @@
public class JAXRSLoggingAtomPushSpringTest extends AbstractClientServerTestBase {
- private static List<Element> retrieved = new ArrayList<Element>();
-
+ private JAXBContext context;
+ private int fakyLogger;
+ private int namedLogger;
+ private int resourceLogger;
+ private int throwables;
+
@BeforeClass
public static void beforeClass() throws Exception {
// must be 'in-process' to communicate with inner class in single JVM
@@ -58,53 +68,367 @@
}
@Before
- public void before() {
- retrieved.clear();
+ public void before() throws Exception {
+ Resource.clear();
+ Resource2.clear();
+ Resource3.clear();
+ Resource4.clear();
+ Resource5.clear();
+ context = JAXBContext.newInstance(LogRecords.class,
+ org.apache.cxf.jaxrs.ext.logging.LogRecord.class);
}
+ @Test
+ public void testFeedsWithLogRecordsOneEntry() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:9080/root");
+ wc.path("/log").get();
+ Thread.sleep(3000);
+ List<Feed> elements = Resource.getElements();
+ assertEquals(8, elements.size());
+
+ resetCounters();
+ for (Feed feed : elements) {
+ List<Entry> entries = feed.getEntries();
+ assertEquals(1, entries.size());
+ Entry e = entries.get(0);
+ LogRecords records = readLogRecords(e.getContent());
+ List<org.apache.cxf.jaxrs.ext.logging.LogRecord> list = records.getLogRecords();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ updateCounters(list.get(0), "Resource");
+ }
+
+ verifyCounters();
+ }
+
+ @Test
+ public void testFeedsWithBatchLogRecordsOneEntry() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:9080/batch");
+ wc.path("/log").get();
+ Thread.sleep(3000);
+ List<Feed> elements = Resource2.getElements();
+ assertEquals(2, elements.size());
+
+ resetCounters();
+ for (Feed feed : elements) {
+ List<Entry> entries = feed.getEntries();
+ assertEquals(4, entries.size());
+
+ for (Entry e : entries) {
+ updateCounters(readLogRecord(e.getContent()), "Resource2");
+ }
+ }
+
+ verifyCounters();
+
+ }
+
+ @Test
+ public void testEntriesWithLogRecordsOneEntry() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:9080/entries");
+ wc.path("/log").get();
+ Thread.sleep(3000);
+ List<Entry> elements = Resource3.getElements();
+ assertEquals(8, elements.size());
+
+ resetCounters();
+
+ for (Entry e : elements) {
+ updateCounters(readLogRecord(e.getContent()), "Resource3");
+ }
+
+ verifyCounters();
+
+ }
+
+ @Test
+ public void testManyEntries() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:9080/entriesMany");
+ wc.path("/log").get();
+ Thread.sleep(3000);
+ List<Entry> elements = Resource4.getElements();
+ assertEquals(4, elements.size());
+
+ resetCounters();
+
+ for (Entry e : elements) {
+ LogRecords records = readLogRecords(e.getContent());
+ List<org.apache.cxf.jaxrs.ext.logging.LogRecord> list = records.getLogRecords();
+ assertNotNull(list);
+ assertEquals(2, list.size());
+ for (org.apache.cxf.jaxrs.ext.logging.LogRecord record : list) {
+ updateCounters(record, "Resource4");
+ }
+
+ }
+ verifyCounters();
+ }
+
+ @Test
+ public void testFeedsWithLogRecordsExtension() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:9080/extensions");
+ wc.path("/log").get();
+ Thread.sleep(3000);
+ List<Feed> elements = Resource5.getElements();
+ assertEquals(8, elements.size());
+
+ resetCounters();
+ for (Feed feed : elements) {
+ List<Entry> entries = feed.getEntries();
+ assertEquals(1, entries.size());
+ Entry e = entries.get(0);
+ LogRecords records = readLogRecordsExtension(e);
+ List<org.apache.cxf.jaxrs.ext.logging.LogRecord> list = records.getLogRecords();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ updateCounters(list.get(0), "Resource5");
+ }
+
+ verifyCounters();
+ }
+
@Ignore
- @Path("/")
+ @Path("/root")
public static class Resource {
private static final Logger LOG1 = LogUtils.getL7dLogger(Resource.class);
private static final Logger LOG2 = LogUtils.getL7dLogger(Resource.class, null, "namedLogger");
+
+ private static List<Feed> feeds = new ArrayList<Feed>();
+
+ @GET
+ @Path("/log")
+ public void doLogging() {
+ doLog(LOG1, LOG2);
+ }
+ @POST
+ @Path("/feeds")
+ public void consume(Feed feed) {
+ feed.toString();
+ synchronized (Resource.class) {
+ feeds.add(feed);
+ }
+ }
+
+ public static void clear() {
+ feeds.clear();
+ }
+
+ public static synchronized List<Feed> getElements() {
+ return new ArrayList<Feed>(feeds);
+ }
+ }
+
+ @Ignore
+ @Path("/batch")
+ public static class Resource2 {
+ private static final Logger LOG1 = LogUtils.getL7dLogger(Resource2.class);
+ private static final Logger LOG2 = LogUtils.getL7dLogger(Resource2.class, null, "namedLogger");
+
+ private static List<Feed> feeds = new ArrayList<Feed>();
+
@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!");
+ doLog(LOG1, LOG2);
}
- // 2. ATOM push handler should populate logs here
@POST
- @Path("/feed")
+ @Path("/feeds")
public void consume(Feed feed) {
- // System.out.println(feed);
- retrieved.add(feed);
+ feed.toString();
+ synchronized (Resource2.class) {
+ feeds.add(feed);
+ }
+ }
+
+ public static void clear() {
+ feeds.clear();
+ }
+
+ public static synchronized List<Feed> getElements() {
+ return new ArrayList<Feed>(feeds);
}
}
+
+ @Ignore
+ @Path("/entries")
+ public static class Resource3 {
+ private static final Logger LOG1 = LogUtils.getL7dLogger(Resource3.class);
+ private static final Logger LOG2 = LogUtils.getL7dLogger(Resource3.class, null, "namedLogger");
+
+ private static List<Entry> entries = new ArrayList<Entry>();
+
+ @GET
+ @Path("/log")
+ public void doLogging() {
+ doLog(LOG1, LOG2);
+ }
- @Test
- public void testLogEvents() throws Exception {
- WebClient wc = WebClient.create("http://localhost:9080");
- wc.path("/log").get();
- Thread.sleep(1000);
- assertEquals(7, retrieved.size());
+ @POST
+ @Path("/entries")
+ public void consume(Entry entry) {
+ entry.toString();
+ synchronized (Resource3.class) {
+ entries.add(entry);
+ }
+ }
+
+ public static void clear() {
+ entries.clear();
+ }
+
+ public static synchronized List<Entry> getElements() {
+ return new ArrayList<Entry>(entries);
+ }
+ }
+
+ @Ignore
+ @Path("/entriesMany")
+ public static class Resource4 {
+ private static final Logger LOG1 = LogUtils.getL7dLogger(Resource4.class);
+ private static final Logger LOG2 = LogUtils.getL7dLogger(Resource4.class, null, "namedLogger");
+
+ private static List<Entry> entries = new ArrayList<Entry>();
+
+ @GET
+ @Path("/log")
+ public void doLogging() {
+ doLog(LOG1, LOG2);
+ }
+
+ @POST
+ @Path("/entries")
+ public void consume(Entry entry) {
+ entry.toString();
+ synchronized (Resource4.class) {
+ entries.add(entry);
+ }
+ }
+
+ public static void clear() {
+ entries.clear();
+ }
+
+ public static synchronized List<Entry> getElements() {
+ return new ArrayList<Entry>(entries);
+ }
+ }
+
+ @Ignore
+ @Path("/extensions")
+ public static class Resource5 {
+ private static final Logger LOG1 = LogUtils.getL7dLogger(Resource5.class);
+ private static final Logger LOG2 = LogUtils.getL7dLogger(Resource5.class, null, "namedLogger");
+
+ private static List<Feed> feeds = new ArrayList<Feed>();
+
+ @GET
+ @Path("/log")
+ public void doLogging() {
+ doLog(LOG1, LOG2);
+ }
+
+ @POST
+ @Path("/feeds")
+ public void consume(Feed feed) {
+ feed.toString();
+ synchronized (Resource5.class) {
+ feeds.add(feed);
+ }
+ }
+
+ public static void clear() {
+ feeds.clear();
+ }
+
+ public static List<Feed> getElements() {
+ return new ArrayList<Feed>(feeds);
+ }
+ }
+
+ private static void doLog(Logger l1, Logger l2) {
+ l1.severe("severe message");
+ l1.warning("warning message");
+ l1.info("info message");
+ LogRecord r = new LogRecord(Level.FINE, "fine message");
+ r.setThrown(new IllegalArgumentException("tadaam"));
+ l1.log(r);
+ r = new LogRecord(Level.FINER, "finer message with {0} and {1}");
+ r.setParameters(new Object[] {
+ "param1", "param2"
+ });
+ r.setLoggerName("faky-logger");
+ l1.log(r);
+ l1.finest("finest message");
+
+ // for LOG2 only 'warning' and above messages should be logged
+ l2.severe("severe message");
+ l2.severe("severe message2");
+ l2.info("info message - should not pass!");
+ l2.finer("finer message - should not pass!");
+ }
+
+ private LogRecords readLogRecords(String value) throws Exception {
+ return (LogRecords)context.createUnmarshaller().unmarshal(new StringReader(value));
+ }
+
+ private org.apache.cxf.jaxrs.ext.logging.LogRecord readLogRecord(String value) throws Exception {
+ return (org.apache.cxf.jaxrs.ext.logging.LogRecord)
+ context.createUnmarshaller().unmarshal(new StringReader(value));
+ }
+
+ private LogRecords readLogRecordsExtension(Entry e) throws Exception {
+ ExtensibleElement el = e.getExtension(new QName("http://cxf.apache.org/log", "logRecords", "log"));
+ LogRecords records = new LogRecords();
+ List<org.apache.cxf.jaxrs.ext.logging.LogRecord> list =
+ new ArrayList<org.apache.cxf.jaxrs.ext.logging.LogRecord>();
+ for (Element element : el.getElements()) {
+ org.apache.cxf.jaxrs.ext.logging.LogRecord record =
+ new org.apache.cxf.jaxrs.ext.logging.LogRecord();
+ Element loggerName = element.getFirstChild(
+ new QName("http://cxf.apache.org/log", "loggerName", "log"));
+ if (loggerName != null) {
+ record.setLoggerName(loggerName.getText());
+ }
+ Element throwable = element.getFirstChild(
+ new QName("http://cxf.apache.org/log", "throwable", "log"));
+ if (throwable != null) {
+ record.setThrowable(throwable.getText());
+ }
+ list.add(record);
+ }
+ records.setLogRecords(list);
+ return records;
+ }
+
+ private void updateCounters(org.apache.cxf.jaxrs.ext.logging.LogRecord record, String clsName) {
+ String name = record.getLoggerName();
+ if (name != null && name.length() > 0) {
+ if (("org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$" + clsName).equals(name)) {
+ resourceLogger++;
+ } else if ("namedLogger".equals(name)) {
+ namedLogger++;
+ } else if ("faky-logger".equals(name)) {
+ fakyLogger++;
+ }
+ } else {
+ assertNotNull(record.getThrowable());
+ throwables++;
+ }
+ }
+
+ private void resetCounters() {
+ fakyLogger = 0;
+ namedLogger = 0;
+ resourceLogger = 0;
+ throwables = 0;
+ }
+
+ private void verifyCounters() {
+ assertEquals(1, throwables);
+ assertEquals(4, resourceLogger);
+ assertEquals(2, namedLogger);
+ assertEquals(1, fakyLogger);
}
}
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushTest.java?rev=892237&r1=892236&r2=892237&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPushTest.java Fri Dec 18 12:23:54 2009
@@ -19,9 +19,10 @@
package org.apache.cxf.systest.jaxrs;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
@@ -60,12 +61,14 @@
public class JAXRSLoggingAtomPushTest {
private static final Logger LOG = LogUtils.getL7dLogger(JAXRSLoggingAtomPushTest.class);
private static Server server;
- private static List<Feed> feeds = new ArrayList<Feed>();
- private static List<Entry> entries = new ArrayList<Entry>();
-
+
@Ignore
@Path("/")
public static class Resource {
+
+ private static Queue<Feed> feeds = new ConcurrentLinkedQueue<Feed>();
+ private static Queue<Entry> entries = new ConcurrentLinkedQueue<Entry>();
+
@POST
public void consume(Feed feed) {
feeds.add(feed);
@@ -76,6 +79,11 @@
public void consume(Entry entry) {
entries.add(entry);
}
+
+ public static void clear() {
+ feeds.clear();
+ entries.clear();
+ }
}
@SuppressWarnings("unchecked")
@@ -131,8 +139,7 @@
@Before
public void before() throws Exception {
- feeds.clear();
- entries.clear();
+ Resource.clear();
}
@Test
@@ -140,8 +147,8 @@
configureLogging("resources/logging_atompush.properties");
logSixEvents(LOG);
// need to wait: multithreaded and client-server journey
- Thread.sleep(1000);
- assertEquals("Different logged events count;", 6, feeds.size());
+ Thread.sleep(3000);
+ assertEquals("Different logged events count;", 6, Resource.feeds.size());
}
@Test
@@ -149,9 +156,9 @@
configureLogging("resources/logging_atompush_batch.properties");
logSixEvents(LOG);
// need to wait: multithreaded and client-server journey
- Thread.sleep(1000);
+ Thread.sleep(3000);
// 6 events / 3 element batch = 2 feeds expected
- assertEquals("Different logged events count;", 2, feeds.size());
+ assertEquals("Different logged events count;", 2, Resource.feeds.size());
}
@Test
@@ -165,9 +172,9 @@
log.setLevel(Level.ALL);
logSixEvents(log);
// need to wait: multithreaded and client-server journey
- Thread.sleep(1000);
+ Thread.sleep(3000);
// 6 events / 2 element batch = 3 feeds expected
- assertEquals("Different logged events count;", 3, feeds.size());
+ assertEquals("Different logged events count;", 3, Resource.feeds.size());
}
@Test
@@ -195,9 +202,9 @@
log.setLevel(Level.ALL);
logSixEvents(log);
// need to wait: multithreaded and client-server journey
- Thread.sleep(1000);
+ Thread.sleep(3000);
// 6 events / 2 element batch = 3 feeds expected
- assertEquals("Different logged events count;", 3, feeds.size());
+ assertEquals("Different logged events count;", 3, Resource.feeds.size());
}
@Test
@@ -205,9 +212,9 @@
configureLogging("resources/logging_atompush_atompub.properties");
logSixEvents(LOG);
// need to wait: multithreaded and client-server journey
- Thread.sleep(1000);
+ Thread.sleep(3000);
// 6 events logged as entries
- assertEquals("Different logged events count;", 6, entries.size());
+ assertEquals("Different logged events count;", 6, Resource.entries.size());
}
}
Modified: 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=892237&r1=892236&r2=892237&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml (original)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompush/WEB-INF/beans.xml Fri Dec 18 12:23:54 2009
@@ -25,12 +25,14 @@
-->
<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"
+ xmlns:util="http://www.springframework.org/schema/util"
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">
+http://cxf.apache.org/jaxrs
+http://cxf.apache.org/schemas/jaxrs.xsd
+http://www.springframework.org/schema/util
+http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
@@ -38,14 +40,110 @@
<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="multiplicity" value="one"/>
<property name="loggers"
value="
org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource:ALL,
namedLogger:WARN" />
+ <property name="deliverer">
+ <ref bean="webDeliverer" />
+ </property>
+ </bean>
+
+ <bean id="webDeliverer" class="org.apache.cxf.jaxrs.ext.logging.atom.deliverer.WebClientDeliverer">
+ <constructor-arg ref="webClient"/>
+ </bean>
+
+ <bean id="webClient" class="org.apache.cxf.jaxrs.client.WebClient"
+factory-method="create">
+ <constructor-arg type="java.lang.String" value="http://localhost:9080/root/feeds" />
+ <constructor-arg ref="feedProvider" />
+ </bean>
+
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+ <property name="batchSize" value="4"/>
+ <property name="loggers"
+ value="
+ org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource2:ALL,
+ namedLogger:WARN" />
+ <property name="url" value="http://localhost:9080/batch/feeds"/>
+ </bean>
+
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+ <property name="output" value="entry"/>
+ <property name="loggers"
+ value="
+ org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource3:ALL,
+ namedLogger:WARN" />
+ <property name="deliverer">
+ <ref bean="webDeliverer3" />
+ </property>
</bean>
+ <bean id="webDeliverer3" class="org.apache.cxf.jaxrs.ext.logging.atom.deliverer.WebClientDeliverer">
+ <constructor-arg ref="webClient3"/>
+ </bean>
+
+ <bean id="webClient3" class="org.apache.cxf.jaxrs.client.WebClient"
+factory-method="create">
+ <constructor-arg type="java.lang.String" value="http://localhost:9080/entries/entries" />
+ <constructor-arg ref="entryProvider" />
+ </bean>
+
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+ <property name="output" value="entry"/>
+ <property name="multiplicity" value="many"/>
+ <property name="batchSize" value="2"/>
+ <property name="loggers"
+ value="
+ org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource4:ALL,
+ namedLogger:WARN" />
+ <property name="url" value="http://localhost:9080/entriesMany/entries"/>
+ </bean>
+
+ <bean class="org.apache.cxf.jaxrs.ext.logging.atom.AtomPushBean"
+ init-method="init">
+ <property name="multiplicity" value="one"/>
+ <property name="format" value="extension"/>
+ <property name="loggers"
+ value="
+ org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource5:ALL,
+ namedLogger:WARN" />
+ <property name="url" value="http://localhost:9080/extensions/feeds"/>
+ </bean>
+
+ <util:list id="feedProvider">
+ <ref bean="feed"/>
+ </util:list>
+
+ <util:list id="entryProvider">
+ <ref bean="entry"/>
+ </util:list>
+
+ <bean id="feed" class="org.apache.cxf.jaxrs.provider.AtomFeedProvider">
+ <property name="formattedOutput" value="true"/>
+ </bean>
+ <bean id="entry" class="org.apache.cxf.jaxrs.provider.AtomEntryProvider">
+ <property name="formattedOutput" value="true"/>
+ </bean>
+
+ <jaxrs:server id="atomserver" address="/">
+ <jaxrs:serviceBeans>
+ <bean class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource"/>
+ <bean class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource2"/>
+ <bean class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource3"/>
+ <bean class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource4"/>
+ <bean class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPushSpringTest$Resource5"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="feed" />
+ <ref bean="entry" />
+ </jaxrs:providers>
+ </jaxrs:server>
+
<!--
Other config samples:
@@ -69,23 +167,7 @@
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 -->