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 2011/03/01 18:52:26 UTC
svn commit: r1075945 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/
rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/
rt/management-web/src/...
Author: sergeyb
Date: Tue Mar 1 17:52:26 2011
New Revision: 1075945
URL: http://svn.apache.org/viewvc?rev=1075945&view=rev
Log:
[CXF-3370] Initial support for searching for individual log entries with related fixes to search extensions
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/FiqlParser.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalSearchContext.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java
cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/LogRecord.java
cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/atom/AtomPullServer.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPullSpringTest.java
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompull/WEB-INF/beans.xml
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java Tue Mar 1 17:52:26 2011
@@ -22,8 +22,8 @@ import java.beans.IntrospectionException
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
@@ -34,8 +34,8 @@ class Beanspector<T> {
private Class<T> tclass;
private T tobj;
- private Map<String, Method> getters = new HashMap<String, Method>();
- private Map<String, Method> setters = new HashMap<String, Method>();
+ private Map<String, Method> getters = new LinkedHashMap<String, Method>();
+ private Map<String, Method> setters = new LinkedHashMap<String, Method>();
public Beanspector(Class<T> tclass) {
if (tclass == null) {
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/FiqlParser.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/FiqlParser.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/FiqlParser.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/FiqlParser.java Tue Mar 1 17:52:26 2011
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@@ -292,7 +293,7 @@ public class FiqlParser<T> {
if (!hasSubtree && AND.equals(operator)) {
try {
// Optimization: single SimpleSearchCondition for 'AND' conditions
- Map<String, ConditionType> map = new HashMap<String, ConditionType>();
+ Map<String, ConditionType> map = new LinkedHashMap<String, ConditionType>();
beanspector.instantiate();
for (ASTNode<T> node : subnodes) {
FiqlParser<T>.Comparison comp = (Comparison)node;
@@ -348,9 +349,19 @@ public class FiqlParser<T> {
public SearchCondition<T> build() throws FiqlParseException {
T cond = createTemplate(name, value);
ConditionType ct = operatorsMap.get(operator);
- return new SimpleSearchCondition<T>(ct, cond);
+
+ if (isPrimitive(cond)) {
+ return new SimpleSearchCondition<T>(ct, cond);
+ } else {
+ return new SimpleSearchCondition<T>(Collections.singletonMap(name, ct),
+ cond);
+ }
}
+ private boolean isPrimitive(T pojo) {
+ return pojo.getClass().getName().startsWith("java.lang");
+ }
+
private T createTemplate(String setter, Object val) throws FiqlParseException {
try {
beanspector.instantiate().setValue(setter, val);
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java Tue Mar 1 17:52:26 2011
@@ -18,6 +18,24 @@
*/
package org.apache.cxf.jaxrs.ext.search;
+/**
+ * Represents the current search expression
+ */
public interface SearchContext {
+
+ /**
+ * Returns the typed search condition representing the search expression
+ *
+ * @param cls the type of the bean(s) the new search condition will
+ * attempt to match
+ * @return the search condition
+ */
<T> SearchCondition<T> getCondition(Class<T> cls);
+
+
+ /**
+ * Returns the actual query expression
+ * @return the expression
+ */
+ String getSearchExpression();
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java Tue Mar 1 17:52:26 2011
@@ -37,7 +37,7 @@ public class SearchContextImpl implement
public <T> SearchCondition<T> getCondition(Class<T> cls) {
FiqlParser<T> parser = getParser(cls);
- String expression = getExpression();
+ String expression = getSearchExpression();
if (expression != null) {
try {
return parser.parse(expression);
@@ -50,7 +50,7 @@ public class SearchContextImpl implement
}
- private String getExpression() {
+ public String getSearchExpression() {
String queryStr = (String)message.get(Message.QUERY_STRING);
if (queryStr != null
&& (queryStr.contains(SHORT_SEARCH_QUERY) || queryStr.contains(SEARCH_QUERY))) {
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java Tue Mar 1 17:52:26 2011
@@ -21,8 +21,8 @@ package org.apache.cxf.jaxrs.ext.search;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -235,7 +235,7 @@ public class SimpleSearchCondition<T> im
*/
private Map<String, Object> getGettersAndValues() {
- Map<String, Object> getters2values = new HashMap<String, Object>();
+ Map<String, Object> getters2values = new LinkedHashMap<String, Object>();
Beanspector<T> beanspector = new Beanspector<T>(condition);
for (String getter : beanspector.getGettersNames()) {
Object value = getValue(beanspector, getter, condition);
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalSearchContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalSearchContext.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalSearchContext.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalSearchContext.java Tue Mar 1 17:52:26 2011
@@ -32,4 +32,7 @@ public class ThreadLocalSearchContext ex
}
+ public String getSearchExpression() {
+ return get().getSearchExpression();
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java Tue Mar 1 17:52:26 2011
@@ -22,6 +22,7 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
import javax.xml.datatype.DatatypeFactory;
@@ -164,6 +165,16 @@ public class FiqlParserTest extends Asse
@Test
public void testParseComplex1() throws FiqlParseException {
SearchCondition<Condition> filter = parser.parse("name==ami*;level=gt=10");
+ assertEquals(ConditionType.AND, filter.getConditionType());
+
+ List<SearchCondition<Condition>> conditions = filter.getSearchConditions();
+ assertEquals(2, conditions.size());
+ PrimitiveStatement st1 = conditions.get(0).getStatement();
+ assertEquals(ConditionType.EQUALS, st1.getCondition());
+
+ PrimitiveStatement st2 = conditions.get(1).getStatement();
+ assertEquals(ConditionType.GREATER_THAN, st2.getCondition());
+
assertTrue(filter.isMet(new Condition("amichalec", 12, new Date())));
assertTrue(filter.isMet(new Condition("ami", 12, new Date())));
assertFalse(filter.isMet(new Condition("ami", 8, null)));
@@ -182,6 +193,17 @@ public class FiqlParserTest extends Asse
@Test
public void testParseComplex2() throws FiqlParseException {
SearchCondition<Condition> filter = parser.parse("name==ami*,level=gt=10");
+ assertEquals(ConditionType.OR, filter.getConditionType());
+
+ List<SearchCondition<Condition>> conditions = filter.getSearchConditions();
+ assertEquals(2, conditions.size());
+
+ PrimitiveStatement st1 = conditions.get(0).getStatement();
+ assertEquals(ConditionType.EQUALS, st1.getCondition());
+
+ PrimitiveStatement st2 = conditions.get(1).getStatement();
+ assertEquals(ConditionType.GREATER_THAN, st2.getCondition());
+
assertTrue(filter.isMet(new Condition("ami", 0, new Date())));
assertTrue(filter.isMet(new Condition("foo", 20, null)));
assertFalse(filter.isMet(new Condition("foo", 0, null)));
Modified: cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/LogRecord.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/LogRecord.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/LogRecord.java (original)
+++ cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/LogRecord.java Tue Mar 1 17:52:26 2011
@@ -88,7 +88,9 @@ public class LogRecord {
record.setLevel(LogLevel.fromJUL(julRecord.getLevel()));
record.setLoggerName(julRecord.getLoggerName());
if (julRecord.getThrown() != null) {
- record.setThrowable(julRecord.getThrown());
+ StringWriter sw = new StringWriter();
+ julRecord.getThrown().printStackTrace(new PrintWriter(sw));
+ record.setThrowable(sw.getBuffer().toString());
}
if (julRecord.getParameters() != null) {
record.setMessage(MessageFormat.format(julRecord.getMessage(), julRecord.getParameters()));
@@ -169,13 +171,6 @@ public class LogRecord {
this.throwable = throwable;
}
- public void setThrowable(Throwable thr) {
- Validate.notNull(thr, "throwable is null");
- StringWriter sw = new StringWriter();
- thr.printStackTrace(new PrintWriter(sw));
- this.throwable = sw.getBuffer().toString();
- }
-
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(obj, this);
Modified: cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/atom/AtomPullServer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/atom/AtomPullServer.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/atom/AtomPullServer.java (original)
+++ cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/atom/AtomPullServer.java Tue Mar 1 17:52:26 2011
@@ -36,6 +36,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.apache.abdera.model.Entry;
@@ -47,6 +48,7 @@ import org.apache.cxf.jaxrs.ext.search.O
import org.apache.cxf.jaxrs.ext.search.PrimitiveStatement;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.SearchConditionVisitor;
+import org.apache.cxf.jaxrs.ext.search.SearchContext;
import org.apache.cxf.management.web.logging.LogLevel;
import org.apache.cxf.management.web.logging.LogRecord;
import org.apache.cxf.management.web.logging.ReadWriteLogStorage;
@@ -60,12 +62,12 @@ public class AtomPullServer extends Abst
private List<LogRecord> records = new LinkedList<LogRecord>();
private WeakHashMap<Integer, Feed> feeds = new WeakHashMap<Integer, Feed>();
private ReadableLogStorage storage;
- private int pageSize = 40;
- private int maxInMemorySize = 500;
+ private int pageSize = 20;
+ private int maxInMemorySize = 1000;
private boolean useArchivedFeeds;
- private int recordsSize;
+ private volatile int recordsSize;
private volatile boolean alreadyClosed;
- private SearchCondition<LogRecord> condition;
+ private SearchCondition<LogRecord> readableStorageCondition;
@Context
private MessageContext context;
@@ -112,7 +114,7 @@ public class AtomPullServer extends Abst
r.setLevel(LogLevel.valueOf(l.getLevel()));
list.add(new SearchConditionImpl(r));
}
- condition = new OrSearchCondition<LogRecord>(list);
+ readableStorageCondition = new OrSearchCondition<LogRecord>(list);
}
initBusProperty();
}
@@ -142,7 +144,7 @@ public class AtomPullServer extends Abst
@GET
@Produces("application/atom+xml")
- public Feed getXmlFeed(@PathParam("id") int page) {
+ public Feed getXmlFeed() {
return getXmlFeedWithPage(1);
}
@@ -162,16 +164,18 @@ public class AtomPullServer extends Abst
}
Feed feed = null;
+ SearchCondition<LogRecord> condition = getCurrentCondition();
synchronized (records) {
- List<LogRecord> list = getSubList(page);
+ List<LogRecord> list = new LinkedList<LogRecord>();
+ int lastPage = fillSubList(list, page, condition);
Collections.sort(list, new LogRecordComparator());
feed = (Feed)new CustomFeedConverter(page).convert(list).get(0);
- setFeedPageProperties(feed, page);
+ setFeedPageProperties(feed, page, lastPage);
}
// if at the moment we've converted n < pageSize number of records only and
// persist a Feed keyed by a page then another reader requesting the same page
// may miss latest records which might've been added since the original request
- if (feed.getEntries().size() == pageSize) {
+ if (condition == null && feed.getEntries().size() == pageSize) {
synchronized (feeds) {
feeds.put(page, feed);
}
@@ -183,7 +187,8 @@ public class AtomPullServer extends Abst
@Produces({"text/html", "application/xhtml+xml" })
@Path("alternate/{id}")
public String getAlternateFeed(@PathParam("id") int page) {
- List<LogRecord> list = getSubList(page);
+ List<LogRecord> list = new LinkedList<LogRecord>();
+ fillSubList(list, page, getCurrentCondition());
Collections.sort(list, new LogRecordComparator());
return convertEntriesToHtml(list);
@@ -193,7 +198,7 @@ public class AtomPullServer extends Abst
@Path("entry/{id}")
@Produces("application/atom+xml;type=entry")
public Entry getEntry(@PathParam("id") int index) {
- List<LogRecord> list = getLogRecords(index);
+ List<LogRecord> list = getLogRecords(index, getCurrentCondition());
return (Entry)new CustomEntryConverter(index).convert(list).get(0);
}
@@ -201,7 +206,7 @@ public class AtomPullServer extends Abst
@Path("entry/alternate/{id}")
@Produces({"text/html", "application/xhtml+xml" })
public String getAlternateEntry(@PathParam("id") int index) {
- List<LogRecord> logRecords = getLogRecords(index);
+ List<LogRecord> logRecords = getLogRecords(index, getCurrentCondition());
return convertEntryToHtml(logRecords.get(0));
}
@@ -212,12 +217,12 @@ public class AtomPullServer extends Abst
return recordsSize;
}
- private List<LogRecord> getLogRecords(int index) {
+ private List<LogRecord> getLogRecords(int index, SearchCondition<LogRecord> theSearch) {
List<LogRecord> list = new LinkedList<LogRecord>();
if (storage != null) {
int storageSize = storage.getSize();
if (recordsSize == -1 || index < storageSize) {
- storage.load(list, condition, index, 1);
+ storage.load(list, theSearch, index, 1);
} else if (index < recordsSize) {
list.add(records.get(index - storageSize));
}
@@ -231,17 +236,16 @@ public class AtomPullServer extends Abst
}
- protected List<LogRecord> getSubList(int page) {
+ protected int fillSubList(List<LogRecord> list, int page, SearchCondition<LogRecord> theSearch) {
if (recordsSize == -1) {
// let the external storage load the records it knows about
- List<LogRecord> list = new LinkedList<LogRecord>();
- storage.load(list, condition, page == 1 ? 0 : (page - 1) * pageSize, pageSize);
- return list;
+ storage.load(list, theSearch, page == 1 ? 0 : (page - 1) * pageSize, pageSize);
+ return page;
}
if (recordsSize == 0) {
- return records;
+ return 1;
}
int fromIndex = 0;
@@ -267,58 +271,93 @@ public class AtomPullServer extends Abst
}
// if we have the storage then try to load from it
+ boolean loaded = false;
if (storage != null) {
if (fromIndex < storage.getSize()) {
int storageSize = storage.getSize();
int maxQuantityToLoad = toIndex > storageSize ? toIndex - storageSize : toIndex - fromIndex;
- List<LogRecord> list = new LinkedList<LogRecord>();
- storage.load(list, condition, fromIndex, maxQuantityToLoad);
+ storage.load(list, theSearch, fromIndex, maxQuantityToLoad);
+ loaded = true;
+
int totalQuantity = toIndex - fromIndex;
if (list.size() < totalQuantity) {
int remaining = totalQuantity - list.size();
if (remaining > records.size()) {
remaining = records.size();
}
- list.addAll(records.subList(0, remaining));
+ fromIndex = 0;
+ toIndex = remaining;
+ loaded = false;
}
- return list;
} else {
fromIndex -= storage.getSize();
toIndex -= storage.getSize();
}
}
- return records.subList(fromIndex, toIndex);
+ if (!loaded) {
+ list.addAll(filterRecords(records.subList(fromIndex, toIndex), theSearch));
+ }
+ if (theSearch != null && list.size() < pageSize && page * pageSize < recordsSize) {
+ return fillSubList(list, page + 1, theSearch);
+ } else {
+ return page;
+ }
+ }
+
+ private List<LogRecord> filterRecords(List<LogRecord> list, SearchCondition<LogRecord> theSearch) {
+ return theSearch == null ? list : theSearch.findAll(list);
}
- protected void setFeedPageProperties(Feed feed, int page) {
+ private SearchCondition<LogRecord> getCurrentCondition() {
+ SearchCondition<LogRecord> current = context.getContext(SearchContext.class)
+ .getCondition(LogRecord.class);
+ if (current == null) {
+ return readableStorageCondition;
+ } else {
+ return current;
+ }
+ }
+
+ private String getSearchExpression() {
+ return context.getContext(SearchContext.class).getSearchExpression();
+ }
+
+ protected void setFeedPageProperties(Feed feed, int page, int lastPage) {
String self = context.getUriInfo().getAbsolutePath().toString();
feed.addLink(self, "self");
+ int feedSize = feed.getEntries().size();
+ String searchExpression = getSearchExpression();
+
String uri = context.getUriInfo().getBaseUriBuilder().path("logs").build().toString();
feed.addLink(uri + "/alternate/" + page, "alternate");
if (!useArchivedFeeds) {
if (recordsSize != -1) {
if (page > 2) {
- feed.addLink(uri, "first");
+ feed.addLink(createLinkUri(uri, searchExpression), "first");
}
- if (page * pageSize < recordsSize) {
- feed.addLink(uri + "/" + (page + 1), "next");
+ if (searchExpression == null && lastPage * pageSize < recordsSize
+ || searchExpression != null && feedSize == pageSize) {
+ feed.addLink(createLinkUri(uri + "/" + (lastPage + 1), searchExpression), "next");
}
- if (page * (pageSize + 1) < recordsSize) {
+ if (searchExpression == null && page * (pageSize + 1) < recordsSize) {
feed.addLink(uri + "/" + (recordsSize / pageSize + 1), "last");
}
- } else if (feed.getEntries().size() == pageSize) {
- feed.addLink(uri + "/" + (page + 1), "next");
+ } else if (feedSize == pageSize) {
+ feed.addLink(createLinkUri(uri + "/" + (page + 1), searchExpression), "next");
}
- if (page > 1) {
+ if (searchExpression == null && page > 1) {
uri = page > 2 ? uri + "/" + (page - 1) : uri;
- feed.addLink(uri, "previous");
+ feed.addLink(createLinkUri(uri, searchExpression), "previous");
}
} else {
- feed.addLink(self, "current");
+ throw new WebApplicationException(Response.serverError()
+ .entity("Archived feeds are not supported yet")
+ .build());
+ // feed.addLink(self, "current");
// TODO : add prev-archive and next-archive; next-archive should not be set if it will point to
// current
// and xmlns:fh="http://purl.org/syndication/history/1.0":archive extension but only if
@@ -327,6 +366,9 @@ public class AtomPullServer extends Abst
}
+ private String createLinkUri(String uri, String search) {
+ return search == null ? uri : uri + "?_s=" + search;
+ }
public void publish(LogRecord record) {
if (alreadyClosed) {
@@ -371,6 +413,12 @@ public class AtomPullServer extends Abst
}
}
+ public synchronized void reset() {
+ records.clear();
+ recordsSize = 0;
+ feeds.clear();
+ }
+
// TODO : this all can be done later on in a simple xslt template
private String convertEntriesToHtml(List<LogRecord> rs) {
StringBuilder sb = new StringBuilder();
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPullSpringTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPullSpringTest.java?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPullSpringTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLoggingAtomPullSpringTest.java Tue Mar 1 17:52:26 2011
@@ -18,7 +18,9 @@
*/
package org.apache.cxf.systest.jaxrs;
+import java.io.PrintWriter;
import java.io.StringReader;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
@@ -28,6 +30,7 @@ import java.util.logging.LogRecord;
import java.util.logging.Logger;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.xml.bind.JAXBContext;
@@ -42,8 +45,8 @@ import org.apache.cxf.jaxrs.provider.Ato
import org.apache.cxf.management.web.logging.LogLevel;
import org.apache.cxf.management.web.logging.ReadWriteLogStorage;
import org.apache.cxf.management.web.logging.ReadableLogStorage;
+import org.apache.cxf.management.web.logging.atom.AtomPullServer;
import org.apache.cxf.testutil.common.AbstractClientServerTestBase;
-import org.apache.cxf.transport.http.HTTPConduit;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -58,6 +61,11 @@ public class JAXRSLoggingAtomPullSpringT
private int namedLogger;
private int resourceLogger;
private int throwables;
+ private int errorLevels;
+ private int traceLevels;
+ private int infoLevels;
+ private int debugLevels;
+ private int warningLevels;
@BeforeClass
public static void beforeClass() throws Exception {
@@ -101,9 +109,6 @@ public class JAXRSLoggingAtomPullSpringT
WebClient wcEntry = WebClient.create("http://localhost:" + PORT + "/atom/logs",
Collections.singletonList(new AtomEntryProvider()))
.accept("application/atom+xml;type=entry");
- HTTPConduit conduit = WebClient.getConfig(wcEntry).getHttpConduit();
- conduit.getClient().setReceiveTimeout(1000000);
- conduit.getClient().setConnectionTimeout(1000000);
for (int i = 0; i < 8; i++) {
Entry entry = wcEntry.path("entry/" + i).get(Entry.class);
entry.toString();
@@ -135,38 +140,51 @@ public class JAXRSLoggingAtomPullSpringT
}
@Test
+ public void testPagedFeedWithQuery() throws Exception {
+ WebClient wcReset = WebClient.create("http://localhost:" + PORT + "/reset");
+ wcReset.post(null);
+
+ WebClient wc = WebClient.create("http://localhost:" + PORT + "/resource2/paged/log");
+ wc.get();
+ Thread.sleep(3000);
+
+ String address = "http://localhost:" + PORT + "/atom2/logs"
+ + "?_s=level==INFO,level==ERROR,level==WARN";
+ verifyPagesWithQuery(address, "next", 3, 2, "theNamedLogger");
+ verifyPagesWithQuery(address, "next", 3, 2, "theNamedLogger");
+ }
+
+ @Test
public void testPagedFeedWithReadWriteStorage() throws Exception {
WebClient wc = WebClient.create("http://localhost:" + PORT + "/resource3/storage");
- HTTPConduit conduit = WebClient.getConfig(wc).getHttpConduit();
- conduit.getClient().setReceiveTimeout(1000000);
- conduit.getClient().setConnectionTimeout(1000000);
wc.path("/log").get();
Thread.sleep(3000);
verifyStoragePages("http://localhost:"
- + PORT + "/atom3/logs", "next", "Resource3", "theStorageLogger");
+ + PORT + "/atom3/logs", "next", "Resource3", "theStorageLogger", false);
List<org.apache.cxf.management.web.logging.LogRecord> list = Storage.getRecords();
assertEquals(4, list.size());
verifyStoragePages("http://localhost:"
- + PORT + "/atom3/logs", "next", "Resource3", "theStorageLogger");
+ + PORT + "/atom3/logs", "next", "Resource3", "theStorageLogger", false);
verifyStoragePages("http://localhost:" + PORT + "/atom3/logs/2", "previous", "Resource3",
- "theStorageLogger");
+ "theStorageLogger", false);
}
@Test
public void testPagedFeedWithReadOnlyStorage() throws Exception {
verifyStoragePages("http://localhost:"
- + PORT + "/atom4/logs", "next", "Resource4", "readOnlyStorageLogger");
+ + PORT + "/atom4/logs", "next", "Resource4", "readOnlyStorageLogger", true);
verifyStoragePages("http://localhost:" + PORT + "/atom4/logs/2", "previous", "Resource4",
- "readOnlyStorageLogger");
+ "readOnlyStorageLogger", true);
}
private void verifyStoragePages(String startAddress, String rel,
- String resourceName, String nLogger)
+ String resourceName, String nLogger,
+ boolean readOnly)
throws Exception {
List<Entry> entries = new ArrayList<Entry>();
String href1 = fillPagedEntries(entries, startAddress, 4, rel, true);
- assertNull(fillPagedEntries(entries, href1, 4, rel, false));
+ fillPagedEntries(entries, href1, 4, rel, "next".equals(rel) && readOnly ? true : false);
assertEquals(8, entries.size());
resetCounters();
@@ -190,7 +208,7 @@ public class JAXRSLoggingAtomPullSpringT
String href1 = fillPagedEntries(entries, startAddress,
firstValue, rel, true);
String href2 = fillPagedEntries(entries, href1, 3, rel, true);
- assertNull(fillPagedEntries(entries, href2, lastValue, rel, false));
+ fillPagedEntries(entries, href2, lastValue, rel, false);
assertEquals(8, entries.size());
resetCounters();
@@ -200,6 +218,26 @@ public class JAXRSLoggingAtomPullSpringT
verifyCounters();
}
+ private void verifyPagesWithQuery(String startAddress, String rel,
+ int firstValue, int lastValue, String nLogger)
+ throws Exception {
+ List<Entry> entries = new ArrayList<Entry>();
+ String hrefRel = fillPagedEntries(entries, startAddress,
+ firstValue, rel, true);
+ hrefRel = fillPagedEntries(entries, hrefRel, lastValue, rel, false);
+ assertEquals(firstValue + lastValue, entries.size());
+
+ resetCounters();
+ for (Entry e : entries) {
+ updateCounters(readLogRecord(e.getContent()), "Resource2", nLogger);
+ }
+ assertEquals(3, errorLevels);
+ assertEquals(1, infoLevels);
+ assertEquals(0, debugLevels);
+ assertEquals(0, traceLevels);
+ assertEquals(1, warningLevels);
+ }
+
private String fillPagedEntries(List<Entry> entries, String href, int expected,
String rel, boolean relExpected) {
Feed feed = getFeed(href);
@@ -211,6 +249,7 @@ public class JAXRSLoggingAtomPullSpringT
assertNotNull(link);
return link.getHref().toString();
} else {
+ assertNull(link);
return null;
}
}
@@ -218,6 +257,8 @@ public class JAXRSLoggingAtomPullSpringT
private Feed getFeed(String address) {
WebClient wc = WebClient.create(address,
Collections.singletonList(new AtomFeedProvider()));
+ WebClient.getConfig(wc).getHttpConduit().getClient().setReceiveTimeout(10000000);
+
Feed feed = wc.accept("application/atom+xml").get(Feed.class);
feed.toString();
return feed;
@@ -265,6 +306,23 @@ public class JAXRSLoggingAtomPullSpringT
}
+ @Path("/")
+ public static class AtomServerReset {
+
+ private AtomPullServer server;
+
+ public void setServer(AtomPullServer s) {
+ this.server = s;
+ }
+
+
+ @POST
+ public void reset() {
+ server.reset();
+ }
+
+ }
+
@Ignore
public static class ExternalStorage implements ReadableLogStorage {
@@ -294,7 +352,9 @@ public class JAXRSLoggingAtomPullSpringT
lr.setLoggerName(loggerName);
lr.setLevel(LogLevel.fromJUL(level));
if (t != null) {
- lr.setThrowable(t);
+ StringWriter sw = new StringWriter();
+ t.printStackTrace(new PrintWriter(sw));
+ lr.setThrowable(sw.getBuffer().toString());
}
records.add(lr);
}
@@ -359,25 +419,36 @@ public class JAXRSLoggingAtomPullSpringT
private static void doLog(Logger l1, Logger l2) {
+
+ // 3 severe, 1 warning, 1 info and 3 debug messages
+
+ // 1
l1.severe("severe message");
+ // 2
l1.warning("warning message");
+ // 3
l1.info("info message");
LogRecord r = new LogRecord(Level.FINE, "fine message");
if ("Resource4".equals(l1.getName())) {
r.setLoggerName(l1.getName());
}
r.setThrown(new IllegalArgumentException("tadaam"));
+ // 4
l1.log(r);
r = new LogRecord(Level.FINER, "finer message with {0} and {1}");
r.setParameters(new Object[] {
"param1", "param2"
});
r.setLoggerName("faky-logger");
+ // 5
l1.log(r);
+ // 6
l1.finest("finest message");
// for LOG2 only 'warning' and above messages should be logged
+ // 7
l2.severe("severe message");
+ // 8
l2.severe("severe message2");
l2.info("info message - should not pass!");
l2.finer("finer message - should not pass!");
@@ -407,6 +478,19 @@ public class JAXRSLoggingAtomPullSpringT
if (record.getThrowable().length() > 0) {
throwables++;
}
+
+ LogLevel level = record.getLevel();
+ if (level == LogLevel.ERROR) {
+ errorLevels++;
+ } else if (level == LogLevel.DEBUG) {
+ debugLevels++;
+ } else if (level == LogLevel.TRACE) {
+ traceLevels++;
+ } else if (level == LogLevel.INFO) {
+ infoLevels++;
+ } else {
+ warningLevels++;
+ }
}
private void resetCounters() {
@@ -414,6 +498,12 @@ public class JAXRSLoggingAtomPullSpringT
namedLogger = 0;
resourceLogger = 0;
throwables = 0;
+
+ errorLevels = 0;
+ infoLevels = 0;
+ debugLevels = 0;
+ traceLevels = 0;
+ warningLevels = 0;
}
private void verifyCounters() {
@@ -421,5 +511,11 @@ public class JAXRSLoggingAtomPullSpringT
assertEquals(4, resourceLogger);
assertEquals(2, namedLogger);
assertEquals(1, fakyLogger);
+
+ assertEquals(3, errorLevels);
+ assertEquals(1, infoLevels);
+ assertEquals(2, debugLevels);
+ assertEquals(1, traceLevels);
+ assertEquals(1, warningLevels);
}
}
Modified: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompull/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompull/WEB-INF/beans.xml?rev=1075945&r1=1075944&r2=1075945&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompull/WEB-INF/beans.xml (original)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_logging_atompull/WEB-INF/beans.xml Tue Mar 1 17:52:26 2011
@@ -150,7 +150,7 @@ http://www.springframework.org/schema/ut
<ref bean="feed" />
</jaxrs:providers>
</jaxrs:server>
-
+
<jaxrs:server id="atomServer4" address="/atom4">
<jaxrs:serviceBeans>
<ref bean="atomPullServer4"/>
@@ -160,6 +160,17 @@ http://www.springframework.org/schema/ut
</jaxrs:providers>
</jaxrs:server>
+
+ <jaxrs:server id="atomReset" address="/reset">
+ <jaxrs:serviceBeans>
+ <ref bean="atomServerReset"/>
+ </jaxrs:serviceBeans>
+ </jaxrs:server>
+
+ <bean id="atomServerReset" class="org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPullSpringTest$AtomServerReset">
+ <property name="server" ref="atomPullServer2"/>
+ </bean>
+
</beans>
<!-- END SNIPPET: beans -->