You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ja...@apache.org on 2013/09/10 17:14:47 UTC
svn commit: r1521521 [3/3] - in /ace/trunk:
org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/
org.apache.ace.agent/ org.apache.ace.agent/src/org/apache/ace/agent/
org.apache.ace.agent/src/org/apache/ace/agent/impl/
org.apache.ace.agent/test/or...
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java Tue Sep 10 15:14:46 2013
@@ -18,6 +18,8 @@
*/
package org.apache.ace.agent.impl;
+import static org.apache.ace.agent.impl.ConnectionUtil.*;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.EOFException;
@@ -47,6 +49,7 @@ import org.apache.ace.agent.ConnectionHa
import org.apache.ace.agent.DiscoveryHandler;
import org.apache.ace.agent.FeedbackChannel;
import org.apache.ace.agent.IdentificationHandler;
+import org.apache.ace.agent.LoggingHandler;
import org.apache.ace.agent.RetryAfterException;
import org.apache.ace.log.LogDescriptor;
import org.apache.ace.log.LogEvent;
@@ -61,13 +64,231 @@ import org.apache.ace.range.SortedRangeS
// TODO: test(coverage)<br/>
// TODO: decouple from range/log API?
public class FeedbackChannelImpl implements FeedbackChannel {
+ /**
+ * The general idea is to provide easy access to a file of records. It supports iterating over records both by
+ * skipping and by reading. Furthermore, files can be truncated. Most methods will make an effort to reset to the
+ * last good record in case of an error -- hence, a call to truncate after an IOException might make the store
+ * readable again.
+ */
+ static class Store {
+ private final RandomAccessFile m_store;
+ private final long m_id;
+ private long m_current;
+
+ /**
+ * Create a new File based Store.
+ *
+ * @param store
+ * the file to use as backend.
+ * @param id
+ * the log id of the store
+ * @throws java.io.IOException
+ * in case the file is not rw.
+ */
+ Store(File store, long id) throws IOException {
+ m_store = new RandomAccessFile(store, "rwd");
+ m_id = id;
+ }
+
+ /**
+ * Store the given record data as the next record.
+ *
+ * @param entry
+ * the data of the record to store.
+ * @throws java.io.IOException
+ * in case of any IO error.
+ */
+ public void append(long id, byte[] entry) throws IOException {
+ long pos = m_store.getFilePointer();
+ try {
+ m_store.seek(m_store.length());
+ m_store.writeLong(id);
+ m_store.writeInt(entry.length);
+ m_store.write(entry);
+ m_store.seek(pos);
+ }
+ catch (IOException ex) {
+ handle(pos, ex);
+ }
+ }
+
+ /**
+ * Release any resources.
+ *
+ * @throws java.io.IOException
+ * in case of any IO error.
+ */
+ public void close() throws IOException {
+ m_store.close();
+ }
+
+ /**
+ * Get the id of the current record.
+ *
+ * @return the idea of the current record.
+ */
+ public long getCurrent() throws IOException {
+ long pos = m_store.getFilePointer();
+ if (m_store.length() == 0) {
+ return 0;
+ }
+ long result = 0;
+ try {
+ m_store.seek(m_current);
+ result = readCurrentID();
+ m_store.seek(pos);
+ }
+ catch (IOException ex) {
+ handle(pos, ex);
+ }
+ return result;
+ }
+
+ /**
+ * Get the log id of this store.
+ *
+ * @return the log id of this store.
+ */
+ public long getId() {
+ return m_id;
+ }
+
+ /**
+ * Determine whether there are any records left based on the current postion.
+ *
+ * @return <code>true</code> if there are still records to be read.
+ * @throws java.io.IOException
+ * in case of an IO error.
+ */
+ public boolean hasNext() throws IOException {
+ return m_store.getFilePointer() < m_store.length();
+ }
+
+ /**
+ * Make sure the store is readable. As a result, the store is at the end of the records.
+ *
+ * @throws java.io.IOException
+ * in case of any IO error.
+ */
+ public void init() throws IOException {
+ reset();
+ try {
+ while (true) {
+ skip();
+ }
+ }
+ catch (EOFException ex) {
+ // done
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public byte[] read() throws IOException {
+ long pos = m_store.getFilePointer();
+ try {
+ if (pos < m_store.length()) {
+ long current = m_store.getFilePointer();
+ long id = m_store.readLong();
+ int next = m_store.readInt();
+ byte[] entry = new byte[next];
+ m_store.readFully(entry);
+ m_current = current;
+ return entry;
+ }
+ }
+ catch (IOException ex) {
+ handle(pos, ex);
+ }
+ return null;
+ }
+
+ public long readCurrentID() throws IOException {
+ long pos = m_store.getFilePointer();
+ try {
+ if (pos < m_store.length()) {
+ long id = m_store.readLong();
+ m_store.seek(pos);
+ return id;
+ }
+ }
+ catch (IOException ex) {
+ handle(pos, ex);
+ }
+ return -1;
+ }
+
+ /**
+ * Reset the store to the beginning of the records
+ *
+ * @throws java.io.IOException
+ * in case of an IO error.
+ */
+ public void reset() throws IOException {
+ m_store.seek(0);
+ m_current = 0;
+ }
+
+ /**
+ * Skip the next record if there is any.
+ *
+ * @throws java.io.IOException
+ * in case of any IO error or if there is no record left.
+ */
+ @SuppressWarnings("unused")
+ public void skip() throws IOException {
+ long pos = m_store.getFilePointer();
+ try {
+ long id = m_store.readLong();
+ int next = m_store.readInt();
+ if (m_store.length() < next + m_store.getFilePointer()) {
+ throw new IOException("Unexpected end of file");
+ }
+ m_store.seek(m_store.getFilePointer() + next);
+ m_current = pos;
+ pos = m_store.getFilePointer();
+ }
+ catch (IOException ex) {
+ handle(pos, ex);
+ }
+ }
+
+ /**
+ * Try to truncate the store at the current record.
+ *
+ * @throws java.io.IOException
+ * in case of any IO error.
+ */
+ public void truncate() throws IOException {
+ m_store.setLength(m_store.getFilePointer());
+ }
+
+ private void handle(long pos, IOException exception) throws IOException {
+ try {
+ m_store.seek(pos);
+ }
+ catch (IOException ex) {
+ // m_log.log(LogService.LOG_WARNING, "Exception during seek!", ex);
+ }
+ throw exception;
+ }
+ }
private static final String DIRECTORY_NAME = "feedback";
private static final String COMMAND_QUERY = "query";
private static final String COMMAND_SEND = "send";
private static final String PARAMETER_TARGETID = "tid";
+
private static final String PARAMETER_LOGID = "logid";
+ // bridging to log api
+ private static Dictionary<String, String> mapToDictionary(Map<String, String> map) {
+ Dictionary<String, String> dictionary = new Hashtable<String, String>();
+ for (Entry<String, String> entry : map.entrySet()) {
+ dictionary.put(entry.getKey(), entry.getValue());
+ }
+ return dictionary;
+ }
+
private final AgentContext m_agentContext;
private final String m_name;
private final File m_baseDir;
@@ -79,160 +300,104 @@ public class FeedbackChannelImpl impleme
};
private Store m_store = null;
+
private long m_highest;
public FeedbackChannelImpl(AgentContext agentContext, String name) throws IOException {
m_agentContext = agentContext;
m_name = name;
m_baseDir = new File(m_agentContext.getWorkDir(), DIRECTORY_NAME);
- if (!m_baseDir.isDirectory() && !m_baseDir.mkdirs())
+ if (!m_baseDir.isDirectory() && !m_baseDir.mkdirs()) {
throw new IllegalArgumentException("Need valid dir");
+ }
initStore();
}
+ public void closeStore() throws IOException {
+ Store store;
+ synchronized (m_store) {
+ store = m_store;
+ }
+ store.close();
+ m_store = null;
+ }
+
@Override
public synchronized void sendFeedback() throws RetryAfterException, IOException {
String identification = getIdentification();
URL serverURL = getServerURL();
+
if (identification == null || serverURL == null) {
+ logWarning("No identification or server URL present, cannot send feedback!");
return;
}
+
+ ConnectionHandler connectionHandler = getConnectionHandler();
URLConnection sendConnection = null;
Writer writer = null;
+
try {
URL sendURL = new URL(serverURL, m_name + "/" + COMMAND_SEND);
- sendConnection = getConnectionHandler().getConnection(sendURL);
+
+ sendConnection = connectionHandler.getConnection(sendURL);
sendConnection.setDoOutput(true);
if (sendConnection instanceof HttpURLConnection) {
((HttpURLConnection) sendConnection).setChunkedStreamingMode(8192);
}
+
writer = new BufferedWriter(new OutputStreamWriter(sendConnection.getOutputStream()));
SortedSet<Long> storeIDs = getStoreIDs();
for (Long storeID : storeIDs) {
URL queryURL = new URL(serverURL, m_name + "/" + COMMAND_QUERY + "?" + PARAMETER_TARGETID + "=" + identification + "&" + PARAMETER_LOGID + "=" + storeID);
- URLConnection queryConnection = getConnectionHandler().getConnection(queryURL);
- synchronizeStore(storeID, queryConnection.getInputStream(), writer);
+ URLConnection queryConnection = connectionHandler.getConnection(queryURL);
+ try {
+ synchronizeStore(storeID, queryConnection.getInputStream(), writer);
+ }
+ finally {
+ close(queryConnection);
+ }
}
writer.flush();
+
ConnectionUtil.checkConnectionResponse(sendConnection);
sendConnection.getContent();
}
finally {
- if (writer != null)
- writer.close();
- if (sendConnection instanceof HttpURLConnection)
- ((HttpURLConnection) sendConnection).disconnect();
+ closeSilently(writer);
+ close(sendConnection);
}
}
@Override
- public synchronized void write(int type, Map<String, String> properties) throws IOException {
- try {
- LogEvent result = new LogEvent(null, m_store.getId(), getNextEventID(), System.currentTimeMillis(), type, mapToDictionary(properties));
- m_store.append(result.getID(), result.toRepresentation().getBytes());
- }
- catch (IOException ex) {
- handleException(m_store, ex);
+ public void write(int type, Map<String, String> properties) throws IOException {
+ synchronized (m_store) {
+ try {
+ LogEvent result = new LogEvent(null, m_store.getId(), getNextEventID(), System.currentTimeMillis(), type, mapToDictionary(properties));
+ m_store.append(result.getID(), result.toRepresentation().getBytes());
+ }
+ catch (IOException ex) {
+ handleException(m_store, ex);
+ }
}
}
- // TODO Is this called?
- public synchronized void closeStore() throws IOException {
- m_store.close();
- m_store = null;
- }
-
- private void initStore() throws IOException {
- SortedSet<Long> storeIDs = getStoreIDs();
- if (storeIDs.isEmpty()) {
- m_store = newFeedbackStore();
- }
- else {
- m_store = createStore(storeIDs.last());
+ private void closeIfNeeded(Store store) {
+ if (store != m_store) {
try {
- m_store.init();
+ store.close();
}
catch (IOException ex) {
- handleException(m_store, ex);
+ // Not much we can do;
}
}
}
- private void synchronizeStore(long storeID, InputStream queryInput, Writer sendWriter) throws IOException {
- long highestLocal = getHighestEventID(storeID);
- if (highestLocal == 0)
- return;
- SortedRangeSet localRange = new SortedRangeSet("1-" + highestLocal);
- SortedRangeSet remoteRange = getQueryDescriptor(queryInput).getRangeSet();
- SortedRangeSet delta = remoteRange.diffDest(localRange);
- RangeIterator rangeIterator = delta.iterator();
- if (!rangeIterator.hasNext())
- return;
- String identification = getIdentification();
- long lowest = rangeIterator.next();
- long highest = delta.getHigh();
- if (lowest <= highest) {
- List<LogEvent> events = getEvents(storeID, lowest, highestLocal > highest ? highest : highestLocal);
- Iterator<LogEvent> iter = events.iterator();
- while (iter.hasNext()) {
- LogEvent current = (LogEvent) iter.next();
- while ((current.getID() > lowest) && rangeIterator.hasNext()) {
- lowest = rangeIterator.next();
- }
- if (current.getID() == lowest) {
- LogEvent event = new LogEvent(identification, current);
- sendWriter.write(event.toRepresentation());
- sendWriter.write("\n");
- }
- }
- }
- }
-
- private LogDescriptor getQueryDescriptor(InputStream queryInput) throws IOException {
- BufferedReader queryReader = null;
- try {
- queryReader = new BufferedReader(new InputStreamReader(queryInput));
- String rangeString = queryReader.readLine();
- if (rangeString == null) {
- throw new IOException("Could not construct LogDescriptor from stream because stream is empty");
- }
- try {
- return new LogDescriptor(rangeString);
- }
- catch (IllegalArgumentException e) {
- throw new IOException("Could not determine highest remote event id, received malformed event range (" + rangeString + ")");
- }
- }
- finally {
- if (queryReader != null) {
- try {
- queryReader.close();
- }
- catch (Exception ex) {
- // not much we can do
- }
- }
- }
- }
-
- private Store newFeedbackStore() throws IOException {
- long storeId = System.currentTimeMillis();
- while (!(new File(m_baseDir, getStoreName(storeId))).createNewFile()) {
- storeId++;
- }
- return new Store(new File(m_baseDir, getStoreName(storeId)), storeId);
- }
-
private Store createStore(long storeId) throws IOException {
return new Store(new File(m_baseDir, getStoreName(storeId)), storeId);
}
- private String getStoreName(long storeId) {
- return m_name + "-" + storeId;
- }
-
- private long getStoreId(String storeName) {
- return Long.parseLong(storeName.replace(m_name + "-", ""));
+ private ConnectionHandler getConnectionHandler() {
+ return m_agentContext.getHandler(ConnectionHandler.class);
}
private List<LogEvent> getEvents(long storeID, long fromEventID, long toEventID) throws IOException {
@@ -261,47 +426,6 @@ public class FeedbackChannelImpl impleme
return result;
}
- private void handleException(Store store, Exception exception) throws IOException {
- // System.err.println(LogService.LOG_WARNING, "Exception accessing the log: "
- // + store.getId(), exception);
- if (store == m_store)
- m_store = newFeedbackStore();
-
- try {
- store.truncate();
- }
- catch (IOException ex) {
- // m_log.log(LogService.LOG_WARNING, "Exception during truncate: "
- // + store.getId(), ex);
- }
- try {
- store.close();
- }
- catch (IOException ex) {
- // Not much we can do
- }
- if (exception instanceof IOException) {
- throw (IOException) exception;
- }
- throw new IOException("Unable to read log entry: "
- + exception.getMessage());
- }
-
- private File[] getStoreFiles() throws IOException {
- File[] files = (File[]) m_baseDir.listFiles(m_fileFilter);
- if (files == null)
- throw new IOException("Unable to list store files in " + m_baseDir.getAbsolutePath());
- return files;
- }
-
- private SortedSet<Long> getStoreIDs() throws IOException {
- File[] files = getStoreFiles();
- SortedSet<Long> storeIDs = new TreeSet<Long>();
- for (int i = 0; i < files.length; i++)
- storeIDs.add(getStoreId(files[i].getName()));
- return storeIDs;
- }
-
private long getHighestEventID(long storeID) throws IOException {
Store store = getStore(storeID);
try {
@@ -322,17 +446,49 @@ public class FeedbackChannelImpl impleme
return -1;
}
- private void closeIfNeeded(Store store) {
- if (store != m_store) {
+ private String getIdentification() {
+ return m_agentContext.getHandler(IdentificationHandler.class).getAgentId();
+ }
+
+ private LoggingHandler getLoggingHandler() {
+ return m_agentContext.getHandler(LoggingHandler.class);
+ }
+
+ private long getNextEventID() throws IOException {
+ return (m_highest = getHighestEventID(m_store.m_id) + 1);
+ }
+
+ private LogDescriptor getQueryDescriptor(InputStream queryInput) throws IOException {
+ BufferedReader queryReader = null;
+ try {
+ queryReader = new BufferedReader(new InputStreamReader(queryInput));
+ String rangeString = queryReader.readLine();
+ if (rangeString == null) {
+ throw new IOException("Could not construct LogDescriptor from stream because stream is empty");
+ }
try {
- store.close();
+ return new LogDescriptor(rangeString);
}
- catch (IOException ex) {
- // Not much we can do;
+ catch (IllegalArgumentException e) {
+ throw new IOException("Could not determine highest remote event id, received malformed event range (" + rangeString + ")");
+ }
+ }
+ finally {
+ if (queryReader != null) {
+ try {
+ queryReader.close();
+ }
+ catch (Exception ex) {
+ // not much we can do
+ }
}
}
}
+ private URL getServerURL() {
+ return m_agentContext.getHandler(DiscoveryHandler.class).getServerUrl();
+ }
+
private Store getStore(long storeID) throws IOException {
if (m_store.getId() == storeID) {
return m_store;
@@ -340,225 +496,120 @@ public class FeedbackChannelImpl impleme
return createStore(storeID);
}
- private long getNextEventID() throws IOException {
- return (m_highest = getHighestEventID(m_store.m_id) + 1);
- }
-
- private ConnectionHandler getConnectionHandler() {
- return m_agentContext.getHandler(ConnectionHandler.class);
+ private File[] getStoreFiles() throws IOException {
+ File[] files = (File[]) m_baseDir.listFiles(m_fileFilter);
+ if (files == null) {
+ throw new IOException("Unable to list store files in " + m_baseDir.getAbsolutePath());
+ }
+ return files;
}
- private String getIdentification() {
- return m_agentContext.getHandler(IdentificationHandler.class).getAgentId();
+ private long getStoreId(String storeName) {
+ return Long.parseLong(storeName.replace(m_name + "-", ""));
}
- private URL getServerURL() {
- return m_agentContext.getHandler(DiscoveryHandler.class).getServerUrl();
+ private SortedSet<Long> getStoreIDs() throws IOException {
+ File[] files = getStoreFiles();
+ SortedSet<Long> storeIDs = new TreeSet<Long>();
+ for (int i = 0; i < files.length; i++) {
+ storeIDs.add(getStoreId(files[i].getName()));
+ }
+ return storeIDs;
}
- // bridging to log api
- private static Dictionary<String, String> mapToDictionary(Map<String, String> map) {
- Dictionary<String, String> dictionary = new Hashtable<String, String>();
- for (Entry<String, String> entry : map.entrySet()) {
- dictionary.put(entry.getKey(), entry.getValue());
- }
- return dictionary;
+ private String getStoreName(long storeId) {
+ return m_name + "-" + storeId;
}
- /**
- * The general idea is to provide easy access to a file of records. It supports iterating over records both by
- * skipping and by reading. Furthermore, files can be truncated. Most methods will make an effort to reset to the
- * last good record in case of an error -- hence, a call to truncate after an IOException might make the store
- * readable again.
- */
- static class Store {
- private final RandomAccessFile m_store;
- private final long m_id;
- private long m_current;
+ private void handleException(Store store, Exception exception) throws IOException {
+ logError("Exception caught while accessing feedback channel store #%d", exception, store.getId());
- /**
- * Create a new File based Store.
- *
- * @param store the file to use as backend.
- * @param id the log id of the store
- * @throws java.io.IOException in case the file is not rw.
- */
- Store(File store, long id) throws IOException {
- m_store = new RandomAccessFile(store, "rwd");
- m_id = id;
+ if (store == m_store) {
+ m_store = newFeedbackStore();
}
-
- /**
- * Get the id of the current record.
- *
- * @return the idea of the current record.
- */
- public long getCurrent() throws IOException {
- long pos = m_store.getFilePointer();
- if (m_store.length() == 0) {
- return 0;
- }
- long result = 0;
- try {
- m_store.seek(m_current);
- result = readCurrentID();
- m_store.seek(pos);
- }
- catch (IOException ex) {
- handle(pos, ex);
- }
- return result;
+ try {
+ store.truncate();
}
-
- /**
- * Get the log id of this store.
- *
- * @return the log id of this store.
- */
- public long getId() {
- return m_id;
+ catch (IOException ex) {
+ logError("Exception caught while truncating feedback channel store #%d", ex, store.getId());
}
- /**
- * Reset the store to the beginning of the records
- *
- * @throws java.io.IOException in case of an IO error.
- */
- public void reset() throws IOException {
- m_store.seek(0);
- m_current = 0;
+ try {
+ store.close();
}
-
- /**
- * Determine whether there are any records left based on the current postion.
- *
- * @return <code>true</code> if there are still records to be read.
- * @throws java.io.IOException in case of an IO error.
- */
- public boolean hasNext() throws IOException {
- return m_store.getFilePointer() < m_store.length();
+ catch (IOException ex) {
+ // Not much we can do
}
- public byte[] read() throws IOException {
- long pos = m_store.getFilePointer();
- try {
- if (pos < m_store.length()) {
- long current = m_store.getFilePointer();
- long id = m_store.readLong();
- int next = m_store.readInt();
- byte[] entry = new byte[next];
- m_store.readFully(entry);
- m_current = current;
- return entry;
- }
- }
- catch (IOException ex) {
- handle(pos, ex);
- }
- return null;
+ if (exception instanceof IOException) {
+ throw (IOException) exception;
}
- public long readCurrentID() throws IOException {
- long pos = m_store.getFilePointer();
- try {
- if (pos < m_store.length()) {
- long id = m_store.readLong();
- m_store.seek(pos);
- return id;
- }
- }
- catch (IOException ex) {
- handle(pos, ex);
- }
- return -1;
- }
+ throw new IOException("Unable to read log entry: " + exception.getMessage());
+ }
- /**
- * Make sure the store is readable. As a result, the store is at the end of the records.
- *
- * @throws java.io.IOException in case of any IO error.
- */
- public void init() throws IOException {
- reset();
- try {
- while (true) {
- skip();
- }
- }
- catch (EOFException ex) {
- // done
- }
+ private void initStore() throws IOException {
+ SortedSet<Long> storeIDs = getStoreIDs();
+ if (storeIDs.isEmpty()) {
+ m_store = newFeedbackStore();
}
-
- /**
- * Skip the next record if there is any.
- *
- * @throws java.io.IOException in case of any IO error or if there is no record left.
- */
- public void skip() throws IOException {
- long pos = m_store.getFilePointer();
+ else {
+ m_store = createStore(storeIDs.last());
try {
- long id = m_store.readLong();
- int next = m_store.readInt();
- if (m_store.length() < next + m_store.getFilePointer()) {
- throw new IOException("Unexpected end of file");
- }
- m_store.seek(m_store.getFilePointer() + next);
- m_current = pos;
- pos = m_store.getFilePointer();
+ m_store.init();
}
catch (IOException ex) {
- handle(pos, ex);
+ handleException(m_store, ex);
}
}
+ }
- /**
- * Store the given record data as the next record.
- *
- * @param entry the data of the record to store.
- * @throws java.io.IOException in case of any IO error.
- */
- public void append(long id, byte[] entry) throws IOException {
- long pos = m_store.getFilePointer();
- try {
- m_store.seek(m_store.length());
- long current = m_store.getFilePointer();
- m_store.writeLong(id);
- m_store.writeInt(entry.length);
- m_store.write(entry);
- m_store.seek(pos);
- }
- catch (IOException ex) {
- handle(pos, ex);
- }
- }
+ private void logError(String msg, Exception cause, Object... args) {
+ getLoggingHandler().logError("feedbackChannel(" + m_name + ")", msg, cause, args);
+ }
- /**
- * Try to truncate the store at the current record.
- *
- * @throws java.io.IOException in case of any IO error.
- */
- public void truncate() throws IOException {
- m_store.setLength(m_store.getFilePointer());
- }
+ private void logWarning(String msg, Object... args) {
+ getLoggingHandler().logWarning("feedbackChannel(" + m_name + ")", msg, null, args);
+ }
- /**
- * Release any resources.
- *
- * @throws java.io.IOException in case of any IO error.
- */
- public void close() throws IOException {
- m_store.close();
+ private Store newFeedbackStore() throws IOException {
+ long storeId = System.currentTimeMillis();
+ // XXX this can fail in case of high concurrent situations!
+ while (!(new File(m_baseDir, getStoreName(storeId))).createNewFile()) {
+ storeId++;
}
+ return new Store(new File(m_baseDir, getStoreName(storeId)), storeId);
+ }
- private void handle(long pos, IOException exception) throws IOException {
- try {
- m_store.seek(pos);
- }
- catch (IOException ex) {
- // m_log.log(LogService.LOG_WARNING, "Exception during seek!", ex);
+ private void synchronizeStore(long storeID, InputStream queryInput, Writer sendWriter) throws IOException {
+ long highestLocal = getHighestEventID(storeID);
+ if (highestLocal == 0) {
+ return;
+ }
+ SortedRangeSet localRange = new SortedRangeSet("1-" + highestLocal);
+ SortedRangeSet remoteRange = getQueryDescriptor(queryInput).getRangeSet();
+ SortedRangeSet delta = remoteRange.diffDest(localRange);
+ RangeIterator rangeIterator = delta.iterator();
+ if (!rangeIterator.hasNext()) {
+ return;
+ }
+ String identification = getIdentification();
+ long lowest = rangeIterator.next();
+ long highest = delta.getHigh();
+ if (lowest <= highest) {
+ List<LogEvent> events = getEvents(storeID, lowest, highestLocal > highest ? highest : highestLocal);
+ Iterator<LogEvent> iter = events.iterator();
+ while (iter.hasNext()) {
+ LogEvent current = (LogEvent) iter.next();
+ while ((current.getID() > lowest) && rangeIterator.hasNext()) {
+ lowest = rangeIterator.next();
+ }
+ if (current.getID() == lowest) {
+ LogEvent event = new LogEvent(identification, current);
+ sendWriter.write(event.toRepresentation());
+ sendWriter.write("\n");
+ }
}
- throw exception;
}
}
}
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackHandlerImpl.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackHandlerImpl.java Tue Sep 10 15:14:46 2013
@@ -19,82 +19,90 @@
package org.apache.ace.agent.impl;
import static org.apache.ace.agent.AgentConstants.CONFIG_FEEDBACK_CHANNELS;
+import static org.apache.ace.agent.impl.InternalConstants.AGENT_CONFIG_CHANGED;
import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.ace.agent.EventListener;
import org.apache.ace.agent.FeedbackChannel;
import org.apache.ace.agent.FeedbackHandler;
/**
* Default implementation of the feedback handler.
*/
-public class FeedbackHandlerImpl extends ComponentBase implements FeedbackHandler {
-
- private final Map<String, FeedbackChannelImpl> m_channels = new HashMap<String, FeedbackChannelImpl>();
- private Set<String> m_channelNames;
- private String m_channelNamesConfig;
+public class FeedbackHandlerImpl extends ComponentBase implements FeedbackHandler, EventListener {
+ private final ConcurrentMap<String, FeedbackChannelImpl> m_channels;
public FeedbackHandlerImpl() {
super("feedback");
+
+ m_channels = new ConcurrentHashMap<String, FeedbackChannelImpl>();
}
@Override
- protected void onStart() throws Exception {
- synchronized (m_channels) {
- ensureChannels(); // fail fast
- }
+ public Set<String> getChannelNames() throws IOException {
+ return m_channels.keySet();
}
@Override
- protected void onStop() throws Exception {
- synchronized (m_channels) {
- clearChannels();
- }
+ public FeedbackChannel getChannel(String name) throws IOException {
+ return m_channels.get(name);
}
@Override
- public Set<String> getChannelNames() throws IOException {
- synchronized (m_channels) {
- ensureChannels();
- return m_channelNames;
+ public void handle(String topic, Map<String, String> payload) {
+ if (AGENT_CONFIG_CHANGED.equals(topic)) {
+ String value = payload.get(CONFIG_FEEDBACK_CHANNELS);
+ if (value != null && !"".equals(value.trim())) {
+ Set<String> seen = new HashSet<String>(m_channels.keySet());
+
+ Set<String> channelNames = split(value);
+ if (channelNames.containsAll(seen) && seen.containsAll(channelNames)) {
+ // Nothing to do...
+ return;
+ }
+
+ for (String channelName : channelNames) {
+ try {
+ m_channels.putIfAbsent(channelName, new FeedbackChannelImpl(getAgentContext(), channelName));
+ seen.remove(channelName);
+ }
+ catch (IOException exception) {
+ logError("Failed to created feedback channel for '%s'", exception, channelName);
+ }
+ }
+
+ for (String oldChannelName : seen) {
+ FeedbackChannelImpl channel = m_channels.remove(oldChannelName);
+ try {
+ channel.closeStore();
+ }
+ catch (IOException exception) {
+ logError("Failed to close feedback channel for '%s'", exception, oldChannelName);
+ }
+ }
+ }
}
}
@Override
- public FeedbackChannel getChannel(String name) throws IOException {
- synchronized (m_channels) {
- ensureChannels();
- return m_channels.get(name);
- }
+ protected void onInit() throws Exception {
+ getEventsHandler().addListener(this);
}
- private void ensureChannels() throws IOException {
- String channelNamesConfig = getConfigurationHandler().get(CONFIG_FEEDBACK_CHANNELS, "auditlog");
- if (m_channelNamesConfig != null && m_channelNamesConfig.equals(channelNamesConfig)) {
- return;
- }
-
- m_channelNamesConfig = channelNamesConfig;
- m_channelNames = Collections.unmodifiableSet(getConfigurationValues(channelNamesConfig));
- m_channels.clear();
- for (String channelName : m_channelNames) {
- m_channels.put(channelName, new FeedbackChannelImpl(getAgentContext(), channelName));
- }
- }
+ @Override
+ protected void onStop() throws Exception {
+ getEventsHandler().removeListener(this);
- private void clearChannels() {
- m_channelNamesConfig = null;
- m_channelNames = null;
m_channels.clear();
}
- // TODO move to util or configurationhandler
- private static Set<String> getConfigurationValues(String value) {
+ private static Set<String> split(String value) {
Set<String> trimmedValues = new HashSet<String>();
if (value != null) {
String[] rawValues = value.split(",");
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java Tue Sep 10 15:14:46 2013
@@ -28,16 +28,15 @@ import org.apache.ace.agent.Identificati
*
*/
public class IdentificationHandlerImpl extends ComponentBase implements IdentificationHandler {
+ /** Default name to use for a new target. */
+ public static final String CONFIG_DEFAULT_AGENTID = "defaultTargetID";
public IdentificationHandlerImpl() {
super("identification");
}
- public static final String CONFIG_DEFAULT_AGENTID = "defaultTargetID";
-
@Override
public String getAgentId() {
- String configValue = getConfigurationHandler().get(CONFIG_IDENTIFICATION_AGENTID, "defaultTargetID");
- return configValue;
+ return getConfigurationHandler().get(CONFIG_IDENTIFICATION_AGENTID, CONFIG_DEFAULT_AGENTID);
}
}
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java Tue Sep 10 15:14:46 2013
@@ -19,73 +19,91 @@
package org.apache.ace.agent.impl;
import static org.apache.ace.agent.AgentConstants.CONFIG_LOGGING_LEVEL;
+import static org.apache.ace.agent.impl.InternalConstants.AGENT_CONFIG_CHANGED;
import java.util.Date;
+import java.util.Map;
+import org.apache.ace.agent.EventListener;
import org.apache.ace.agent.LoggingHandler;
/**
* Default thread-safe {@link LoggingHandler} implementation that logs messages to {@link System.out} .
*/
-public class LoggingHandlerImpl extends ComponentBase implements LoggingHandler {
+public class LoggingHandlerImpl extends ComponentBase implements LoggingHandler, EventListener {
+ private static final Levels DEFAULT = Levels.WARNING;
+
+ private volatile Levels m_logLevel;
public LoggingHandlerImpl() {
super("logging");
+
+ m_logLevel = DEFAULT;
+ }
+
+ @Override
+ public void handle(String topic, Map<String, String> payload) {
+ if (AGENT_CONFIG_CHANGED.equals(topic)) {
+ String newValue = payload.get(CONFIG_LOGGING_LEVEL);
+
+ m_logLevel = fromName(newValue);
+ }
}
@Override
public void logDebug(String component, String message, Throwable exception, Object... args) {
- Levels level = getLogLevel();
- if (level == Levels.DEBUG) {
- log(Levels.DEBUG.name(), component, message, exception, args);
- }
+ log(Levels.DEBUG, component, message, exception, args);
}
@Override
public void logInfo(String component, String message, Throwable exception, Object... args) {
- Levels level = getLogLevel();
- if (level == Levels.DEBUG || level == Levels.INFO) {
- log(Levels.INFO.name(), component, message, exception, args);
- }
+ log(Levels.INFO, component, message, exception, args);
}
@Override
public void logWarning(String component, String message, Throwable exception, Object... args) {
- Levels level = getLogLevel();
- if (level == Levels.DEBUG || level == Levels.INFO || level == Levels.WARNING) {
- log(Levels.WARNING.name(), component, message, exception, args);
- }
+ log(Levels.WARNING, component, message, exception, args);
}
@Override
public void logError(String component, String message, Throwable exception, Object... args) {
- log(Levels.ERROR.name(), component, message, exception, args);
+ log(Levels.ERROR, component, message, exception, args);
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ getEventsHandler().addListener(this);
+ }
+
+ @Override
+ protected void onStop() throws Exception {
+ getEventsHandler().removeListener(this);
}
- private void log(String level, String component, String message, Throwable exception, Object... args) {
+ private void log(Levels logLevel, String component, String message, Throwable exception, Object... args) {
+ if (m_logLevel.ordinal() > logLevel.ordinal()) {
+ // we're not interested at this log entry...
+ return;
+ }
if (args.length > 0) {
message = String.format(message, args);
}
- String line = String.format("[%s] %TT (%s) %s", level, new Date(), component, message);
- System.out.println(line);
+ System.out.printf("[%s] %TT (%s) %s%n", logLevel, new Date(), component, message);
+
if (exception != null) {
exception.printStackTrace(System.out);
}
}
- // TODO performance; replace with configuration events
- private Levels getLogLevel() {
- String config = getConfigurationHandler().get(CONFIG_LOGGING_LEVEL, Levels.INFO.name());
- return fromName(config);
- }
-
private static Levels fromName(String name) {
- name = name.toUpperCase().trim();
+ if (name == null) {
+ return DEFAULT;
+ }
try {
return Levels.valueOf(name.toUpperCase().trim());
}
catch (Exception e) {
- return Levels.ERROR;
+ return DEFAULT;
}
}
}
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java Tue Sep 10 15:14:46 2013
@@ -18,6 +18,10 @@
*/
package org.apache.ace.agent.impl;
+import static org.apache.ace.agent.impl.ConnectionUtil.checkConnectionResponse;
+import static org.apache.ace.agent.impl.ConnectionUtil.close;
+import static org.apache.ace.agent.impl.ConnectionUtil.closeSilently;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -45,7 +49,9 @@ public class UpdateHandlerBase extends C
BufferedReader reader = null;
try {
connection = getConnection(endpoint);
- ConnectionUtil.checkConnectionResponse(connection);
+
+ checkConnectionResponse(connection);
+
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String versionString;
while ((versionString = reader.readLine()) != null) {
@@ -60,68 +66,47 @@ public class UpdateHandlerBase extends C
return versions;
}
finally {
- if (connection != null && connection instanceof HttpURLConnection) {
- ((HttpURLConnection) connection).disconnect();
- }
- if (reader != null) {
- reader.close();
- }
+ closeSilently(reader);
+ close(connection);
+ }
+ }
+
+ protected DownloadHandle getDownloadHandle(URL packageURL) {
+ return getDownloadHandler().getHandle(packageURL);
+ }
+
+ protected String getIdentification() {
+ return getIdentificationHandler().getAgentId();
+ }
+
+ protected InputStream getInputStream(URL packageURL) throws IOException {
+ URLConnection urlConnection = null;
+ // TODO handle problems and retries
+ try {
+ urlConnection = getConnection(packageURL);
+ return urlConnection.getInputStream();
+ }
+ catch (IOException e) {
+ close(urlConnection);
+ throw e;
}
}
protected long getPackageSize(URL url) throws RetryAfterException, IOException {
- long packageSize = -1l;
URLConnection urlConnection = null;
- InputStream inputStream = null;
try {
urlConnection = url.openConnection();
if (urlConnection instanceof HttpURLConnection) {
((HttpURLConnection) urlConnection).setRequestMethod("HEAD");
}
- String dpSizeHeader = urlConnection.getHeaderField(AgentConstants.HEADER_DPSIZE);
- if (dpSizeHeader != null) {
- try {
- packageSize = Long.parseLong(dpSizeHeader);
- }
- catch (NumberFormatException e) {
- // ignore
- }
- }
- return packageSize;
+ return urlConnection.getHeaderFieldLong(AgentConstants.HEADER_DPSIZE, -1L);
}
finally {
- if (urlConnection != null && urlConnection instanceof HttpURLConnection) {
- ((HttpURLConnection) urlConnection).disconnect();
- }
- if (inputStream != null) {
- try {
- inputStream.close();
- }
- catch (IOException e) {
- // ignore
- }
- }
+ close(urlConnection);
}
}
- protected InputStream getInputStream(URL packageURL) throws RetryAfterException, IOException {
- URLConnection urlConnection = null;
- InputStream inputStream = null;
- // TODO handle problems and retries
- urlConnection = getConnection(packageURL);
- inputStream = urlConnection.getInputStream();
- return inputStream;
- }
-
- protected DownloadHandle getDownloadHandle(URL packageURL) {
- return getDownloadHandler().getHandle(packageURL);
- }
-
- protected String getIdentification() {
- return getIdentificationHandler().getAgentId();
- }
-
protected URL getServerURL() throws RetryAfterException {
// FIXME not sure if this is the proper place
URL serverURL = getDiscoveryHandler().getServerUrl();
Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java Tue Sep 10 15:14:46 2013
@@ -77,23 +77,23 @@ public class ConfigurationHandlerImplTes
@Test
public void testConfigSystemProps() throws Exception {
-
String systemKey1 = AgentConstants.CONFIG_KEY_NAMESPACE + "key1";
String systemKey2 = AgentConstants.CONFIG_KEY_NAMESPACE + "key2";
System.setProperty(systemKey1, "value1");
System.setProperty(systemKey2, "value2");
- ConfigurationHandler configurationHandler = new ConfigurationHandlerImpl();
m_agentContextImpl.stop();
- m_agentContextImpl.setHandler(ConfigurationHandler.class, configurationHandler);
+
+ m_agentContextImpl.setHandler(ConfigurationHandler.class, new ConfigurationHandlerImpl());
m_agentContextImpl.start();
- configurationHandler = m_agentContextImpl.getHandler(ConfigurationHandler.class);
+
+ ConfigurationHandler configurationHandler = m_agentContextImpl.getHandler(ConfigurationHandler.class);
assertNotNull(configurationHandler.keySet());
assertEquals(2, configurationHandler.keySet().size());
- assertEquals(configurationHandler.get(systemKey1, "qqq"), "value1");
- assertEquals(configurationHandler.get(systemKey2, "qqq"), "value2");
+ assertEquals(configurationHandler.get(systemKey1, "default1"), "value1");
+ assertEquals(configurationHandler.get(systemKey2, "default2"), "value2");
// System props should be persisted
@@ -101,8 +101,10 @@ public class ConfigurationHandlerImplTes
System.clearProperty(systemKey2);
m_agentContextImpl.stop();
+
m_agentContextImpl.setHandler(ConfigurationHandler.class, new ConfigurationHandlerImpl());
m_agentContextImpl.start();
+
configurationHandler = m_agentContextImpl.getHandler(ConfigurationHandler.class);
assertNotNull(configurationHandler.keySet());
Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java Tue Sep 10 15:14:46 2013
@@ -18,17 +18,13 @@
*/
package org.apache.ace.agent.impl;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.notNull;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -39,6 +35,8 @@ import javax.xml.bind.DatatypeConverter;
import org.apache.ace.agent.AgentConstants;
import org.apache.ace.agent.ConfigurationHandler;
import org.apache.ace.agent.ConnectionHandler;
+import org.apache.ace.agent.ConnectionHandler.Types;
+import org.apache.ace.agent.EventsHandler;
import org.apache.ace.agent.testutil.BaseAgentTest;
import org.apache.ace.agent.testutil.TestWebServer;
import org.testng.annotations.AfterTest;
@@ -48,45 +46,47 @@ import org.testng.annotations.Test;
/**
* Testing {@link ConnectionHandlerImpl},
*/
-// TODO test CLIENT_CERT
public class ConnectionHandlerImplTest extends BaseAgentTest {
static class BasicAuthServlet extends HttpServlet {
-
private static final long serialVersionUID = 1L;
private final String m_authHeader;
public BasicAuthServlet(String username, String password) {
- m_authHeader = "Basic " + DatatypeConverter.printBase64Binary((username + ":" + password).getBytes());
+ m_authHeader = "Basic ".concat(DatatypeConverter.printBase64Binary((username + ":" + password).getBytes()));
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String authHeader = req.getHeader("Authorization");
- if (authHeader == null || !authHeader.equals(m_authHeader))
+ if (authHeader == null || !authHeader.equals(m_authHeader)) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Requires Basic Auth");
- resp.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ resp.setStatus(HttpServletResponse.SC_OK);
+ }
}
}
+ private static final int PORT = 8880;
+ private static final String USERNAME = "john.doe";
+ private static final String PASSWORD = "secret";
+
private TestWebServer m_webServer;
- private String m_user = "Mickey";
- private String m_pass = "Mantle";
private URL m_basicAuthURL;
-
private AgentContextImpl m_agentContext;
@BeforeTest
public void setUpOnceAgain() throws Exception {
+ m_basicAuthURL = new URL("http://localhost:" + PORT + "/basicauth");
- int port = 8880;
- m_basicAuthURL = new URL("http://localhost:" + port + "/basicauth");
- m_webServer = new TestWebServer(port, "/", "generated");
- m_webServer.addServlet(new BasicAuthServlet(m_user, m_pass), "/basicauth/*");
+ m_webServer = new TestWebServer(PORT, "/", "generated");
+ m_webServer.addServlet(new BasicAuthServlet(USERNAME, PASSWORD), "/basicauth/*");
m_webServer.start();
m_agentContext = mockAgentContext();
+ m_agentContext.setHandler(EventsHandler.class, new EventsHandlerImpl(mockBundleContext()));
+ m_agentContext.setHandler(ConfigurationHandler.class, new ConfigurationHandlerImpl());
m_agentContext.setHandler(ConnectionHandler.class, new ConnectionHandlerImpl());
replayTestMocks();
@@ -103,24 +103,30 @@ public class ConnectionHandlerImplTest e
@Test
public void testBasicAuthFORBIDDEN() throws Exception {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put(AgentConstants.CONFIG_CONNECTION_AUTHTYPE, Types.NONE.name());
+
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
+ configurationHandler.putAll(props);
+
ConnectionHandler connectionHandler = m_agentContext.getHandler(ConnectionHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(notNull(String.class), anyObject(String.class))).andReturn(null).anyTimes();
- replay(configurationHandler);
HttpURLConnection connection = (HttpURLConnection) connectionHandler.getConnection(m_basicAuthURL);
+
assertEquals(connection.getResponseCode(), HttpServletResponse.SC_FORBIDDEN);
}
@Test
public void testBasicAuthOK() throws Exception {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put(AgentConstants.CONFIG_CONNECTION_AUTHTYPE, Types.BASIC.name());
+ props.put(AgentConstants.CONFIG_CONNECTION_USERNAME, USERNAME);
+ props.put(AgentConstants.CONFIG_CONNECTION_PASSWORD, PASSWORD);
+
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
+ configurationHandler.putAll(props);
+
ConnectionHandler connectionHandler = m_agentContext.getHandler(ConnectionHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class))).andReturn("BASIC").anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_USERNAME), anyObject(String.class))).andReturn(m_user).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_PASSWORD), anyObject(String.class))).andReturn(m_pass).anyTimes();
- replay(configurationHandler);
+
HttpURLConnection connection = (HttpURLConnection) connectionHandler.getConnection(m_basicAuthURL);
assertEquals(connection.getResponseCode(), HttpServletResponse.SC_OK);
}
Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java Tue Sep 10 15:14:46 2013
@@ -18,11 +18,6 @@
*/
package org.apache.ace.agent.impl;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
@@ -33,6 +28,7 @@ import org.apache.ace.agent.AgentContext
import org.apache.ace.agent.ConfigurationHandler;
import org.apache.ace.agent.ConnectionHandler;
import org.apache.ace.agent.DiscoveryHandler;
+import org.apache.ace.agent.EventsHandler;
import org.apache.ace.agent.testutil.BaseAgentTest;
import org.apache.ace.agent.testutil.TestWebServer;
import org.testng.annotations.AfterTest;
@@ -44,7 +40,8 @@ import org.testng.annotations.Test;
*/
public class DiscoveryHandlerImplTest extends BaseAgentTest {
- private final int PORT = 8882;
+ private static final int PORT = 8882;
+
private TestWebServer m_webServer;
private URL m_availableURL;
private URL m_unavailableURL;
@@ -62,6 +59,8 @@ public class DiscoveryHandlerImplTest ex
m_agentContextImpl = mockAgentContext();
m_agentContext = m_agentContextImpl;
m_agentContextImpl.setHandler(DiscoveryHandler.class, new DiscoveryHandlerImpl());
+ m_agentContextImpl.setHandler(EventsHandler.class, new EventsHandlerImpl(mockBundleContext()));
+ m_agentContextImpl.setHandler(ConfigurationHandler.class, new ConfigurationHandlerImpl());
m_agentContextImpl.setHandler(ConnectionHandler.class, new ConnectionHandlerImpl());
replayTestMocks();
m_agentContextImpl.start();
@@ -79,14 +78,10 @@ public class DiscoveryHandlerImplTest ex
@Test
public void testAvailableURL() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_availableURL.toExternalForm()).anyTimes();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_availableURL.toExternalForm());
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertEquals(discoveryHandler.getServerUrl(), m_availableURL);
}
@@ -94,14 +89,10 @@ public class DiscoveryHandlerImplTest ex
@Test
public void testUnavailableURL_unavailable() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_unavailableURL.toExternalForm()).anyTimes();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_unavailableURL.toExternalForm());
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertNull(discoveryHandler.getServerUrl());
}
@@ -109,50 +100,40 @@ public class DiscoveryHandlerImplTest ex
@Test
public void testUnavailableAfterConfigUpdate() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_availableURL.toExternalForm()).once();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_unavailableURL.toExternalForm()).once();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_availableURL.toExternalForm());
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertEquals(discoveryHandler.getServerUrl(), m_availableURL);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_unavailableURL.toExternalForm());
+
assertNull(discoveryHandler.getServerUrl());
}
@Test
public void testAvailableAfterConfigUpdate() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_unavailableURL.toExternalForm()).once();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_availableURL.toExternalForm()).once();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_unavailableURL.toExternalForm());
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertNull(discoveryHandler.getServerUrl());
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_availableURL.toExternalForm());
+
assertEquals(discoveryHandler.getServerUrl(), m_availableURL);
}
@Test
public void testAvailableAfterUnavailableURL() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn(m_unavailableURL.toExternalForm() + "," + m_availableURL.toExternalForm()).once();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, m_unavailableURL.toExternalForm() + "," + m_availableURL.toExternalForm());
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertEquals(discoveryHandler.getServerUrl(), m_availableURL);
}
@@ -160,14 +141,10 @@ public class DiscoveryHandlerImplTest ex
@Test
public void testEmptyURLConfig() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn("").once();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, "");
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertNull(discoveryHandler.getServerUrl());
}
@@ -175,14 +152,10 @@ public class DiscoveryHandlerImplTest ex
@Test
public void testBadURLConfig() throws Exception {
ConfigurationHandler configurationHandler = m_agentContext.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_CONNECTION_AUTHTYPE), anyObject(String.class)))
- .andReturn(null).anyTimes();
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_DISCOVERY_SERVERURLS), anyObject(String.class)))
- .andReturn("foobar").once();
- expect(configurationHandler.getBoolean(AgentConstants.CONFIG_DISCOVERY_CHECKING, false))
- .andReturn(true).anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, "invalidURL");
+ configurationHandler.put(AgentConstants.CONFIG_DISCOVERY_CHECKING, "true");
+
DiscoveryHandler discoveryHandler = m_agentContext.getHandler(DiscoveryHandler.class);
assertNull(discoveryHandler.getServerUrl());
}
Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/FeedbackHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/FeedbackHandlerImplTest.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/FeedbackHandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/FeedbackHandlerImplTest.java Tue Sep 10 15:14:46 2013
@@ -18,11 +18,8 @@
*/
package org.apache.ace.agent.impl;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
@@ -32,6 +29,7 @@ import java.util.Set;
import org.apache.ace.agent.AgentConstants;
import org.apache.ace.agent.ConfigurationHandler;
+import org.apache.ace.agent.EventsHandler;
import org.apache.ace.agent.FeedbackHandler;
import org.apache.ace.agent.testutil.BaseAgentTest;
import org.testng.annotations.AfterMethod;
@@ -49,7 +47,11 @@ public class FeedbackHandlerImplTest ext
public void setUpAgain(Method method) throws Exception {
m_agentContextImpl = mockAgentContext(method.getName());
replayTestMocks();
+
m_agentContextImpl.setHandler(FeedbackHandler.class, new FeedbackHandlerImpl());
+ m_agentContextImpl.setHandler(EventsHandler.class, new EventsHandlerImpl(mockBundleContext()));
+ m_agentContextImpl.setHandler(ConfigurationHandler.class, new ConfigurationHandlerImpl());
+
m_agentContextImpl.start();
}
@@ -61,33 +63,79 @@ public class FeedbackHandlerImplTest ext
}
@Test
- public void testFeedbackChannelConfig() throws Exception {
+ public void testSingleFeedbackChannelConfig() throws Exception {
ConfigurationHandler configurationHandler = m_agentContextImpl.getHandler(ConfigurationHandler.class);
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_FEEDBACK_CHANNELS),
- anyObject(String.class))).andReturn("auditlog").anyTimes();
- replay(configurationHandler);
+
+ configurationHandler.put(AgentConstants.CONFIG_FEEDBACK_CHANNELS, "auditlog");
FeedbackHandler feedbackHandler = m_agentContextImpl.getHandler(FeedbackHandler.class);
+
Set<String> names = feedbackHandler.getChannelNames();
assertNotNull(names);
- assertTrue(names.size() == 1);
+ assertEquals(1, names.size());
assertTrue(names.contains("auditlog"));
+
assertNotNull(feedbackHandler.getChannel("auditlog"));
- assertNull(feedbackHandler.getChannel("QQQ"));
+ assertNull(feedbackHandler.getChannel("nonExistingChannel"));
+ }
- reset(configurationHandler);
- expect(configurationHandler.get(eq(AgentConstants.CONFIG_FEEDBACK_CHANNELS),
- anyObject(String.class))).andReturn("auditlog, customchannel").anyTimes();
- replay(configurationHandler);
+ @Test
+ public void testUpdateConfigAddFeedbackChannel() throws Exception {
+ ConfigurationHandler configurationHandler = m_agentContextImpl.getHandler(ConfigurationHandler.class);
+
+ configurationHandler.put(AgentConstants.CONFIG_FEEDBACK_CHANNELS, "auditlog");
+
+ FeedbackHandler feedbackHandler = m_agentContextImpl.getHandler(FeedbackHandler.class);
+
+ Set<String> names = feedbackHandler.getChannelNames();
+ assertNotNull(names);
+ assertEquals(1, names.size());
+ assertTrue(names.contains("auditlog"));
+
+ assertNotNull(feedbackHandler.getChannel("auditlog"));
+ assertNull(feedbackHandler.getChannel("nonExistingChannel"));
+
+ configurationHandler.put(AgentConstants.CONFIG_FEEDBACK_CHANNELS, "auditlog, customchannel");
names = feedbackHandler.getChannelNames();
assertNotNull(names);
- assertTrue(names.size() == 2);
+ assertEquals(2, names.size());
assertTrue(names.contains("auditlog"));
assertTrue(names.contains("customchannel"));
+
assertNotNull(feedbackHandler.getChannel("auditlog"));
assertNotNull(feedbackHandler.getChannel("customchannel"));
- assertNull(feedbackHandler.getChannel("QQQ"));
+ assertNull(feedbackHandler.getChannel("nonExistingChannel"));
+ }
+
+ @Test
+ public void testUpdateConfigRemoveFeedbackChannel() throws Exception {
+ ConfigurationHandler configurationHandler = m_agentContextImpl.getHandler(ConfigurationHandler.class);
+
+ configurationHandler.put(AgentConstants.CONFIG_FEEDBACK_CHANNELS, "auditlog, customchannel");
+
+ FeedbackHandler feedbackHandler = m_agentContextImpl.getHandler(FeedbackHandler.class);
+
+ Set<String> names = feedbackHandler.getChannelNames();
+ assertNotNull(names);
+ assertEquals(2, names.size());
+ assertTrue(names.contains("auditlog"));
+ assertTrue(names.contains("customchannel"));
+
+ assertNotNull(feedbackHandler.getChannel("auditlog"));
+ assertNotNull(feedbackHandler.getChannel("customchannel"));
+ assertNull(feedbackHandler.getChannel("nonExistingChannel"));
+
+ configurationHandler.put(AgentConstants.CONFIG_FEEDBACK_CHANNELS, "auditlog");
+
+ names = feedbackHandler.getChannelNames();
+ assertNotNull(names);
+ assertEquals(1, names.size());
+ assertTrue(names.contains("auditlog"));
+ assertFalse(names.contains("customchannel"));
+
+ assertNotNull(feedbackHandler.getChannel("auditlog"));
+ assertNull(feedbackHandler.getChannel("customchannel"));
+ assertNull(feedbackHandler.getChannel("nonExistingChannel"));
}
}
Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java Tue Sep 10 15:14:46 2013
@@ -18,63 +18,95 @@
*/
package org.apache.ace.agent.testutil;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static org.easymock.EasyMock.*;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
+import java.util.concurrent.ScheduledExecutorService;
import org.apache.ace.agent.AgentContext;
import org.apache.ace.agent.AgentContextAware;
import org.apache.ace.agent.impl.AgentContextImpl;
+import org.osgi.framework.BundleContext;
/**
* Simple base class.
*/
public abstract class BaseAgentTest {
+ private final Set<Object> m_mocks = new HashSet<Object>();
- private Set<Object> m_mocks = new HashSet<Object>();
+ protected <T> T addTestMock(Class<T> clazz) {
+ T mock = createNiceMock(clazz);
+ m_mocks.add(mock);
+ return mock;
+ }
+
+ protected void cleanDir(File dir) {
+ if (!dir.isDirectory())
+ throw new IllegalStateException();
+ Stack<File> dirs = new Stack<File>();
+ dirs.push(dir);
+ while (!dirs.isEmpty()) {
+ File currentDir = dirs.pop();
+ File[] files = currentDir.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+ dirs.push(file);
+ }
+ else {
+ file.delete();
+ }
+ }
+ }
+ }
+
+ protected void clearTestMocks() {
+ m_mocks.clear();
+ }
+
+ protected File getWorkDir() {
+ return new File("generated");
+ }
protected AgentContextImpl mockAgentContext() throws Exception {
- return mockAgentContext("" + System.currentTimeMillis());
+ return mockAgentContext("mockAgentContext" + System.currentTimeMillis());
}
protected AgentContextImpl mockAgentContext(String subDir) throws Exception {
File contextDir = new File(getWorkDir(), subDir);
contextDir.mkdirs();
cleanDir(contextDir);
+
AgentContextImpl context = new AgentContextImpl(contextDir);
for (Class<?> handlerClass : AgentContextImpl.KNOWN_HANDLERS) {
- context.setHandler(handlerClass, addTestMock(handlerClass));
+ if (ScheduledExecutorService.class.equals(handlerClass)) {
+ // always inject a proper executor service that simply invokes synchronously...
+ context.setHandler(ScheduledExecutorService.class, new SynchronousExecutorService());
+ }
+ else {
+ setMockedHandler(context, handlerClass);
+ }
}
return context;
}
- protected <T extends Object> T addTestMock(Class<T> clazz) {
- T mock = createNiceMock(clazz);
- m_mocks.add(mock);
- return mock;
+ protected BundleContext mockBundleContext() throws Exception {
+ BundleContext result = createNiceMock(BundleContext.class);
+ expect(result.createFilter(anyObject(String.class))).andReturn(null).anyTimes();
+ replay(result);
+ return result;
}
protected void replayTestMocks() {
- for (Object mock : m_mocks)
+ for (Object mock : m_mocks) {
replay(mock);
+ }
}
- protected void verifyTestMocks() {
- for (Object mock : m_mocks)
- verify(mock);
- }
-
- protected void clearTestMocks() {
- m_mocks.clear();
- }
-
- protected File getWorkDir() {
- return new File("generated");
+ protected <T> void setMockedHandler(AgentContextImpl context, Class<T> clazz) {
+ context.setHandler(clazz, addTestMock(clazz));
}
protected void startHandler(Object handler, AgentContext agentContext) throws Exception {
@@ -89,22 +121,9 @@ public abstract class BaseAgentTest {
}
}
- protected void cleanDir(File dir) {
- if (!dir.isDirectory())
- throw new IllegalStateException();
- Stack<File> dirs = new Stack<File>();
- dirs.push(dir);
- while (!dirs.isEmpty()) {
- File currentDir = dirs.pop();
- File[] files = currentDir.listFiles();
- for (File file : files) {
- if (file.isDirectory()) {
- dirs.push(file);
- }
- else {
- file.delete();
- }
- }
+ protected void verifyTestMocks() {
+ for (Object mock : m_mocks) {
+ verify(mock);
}
}
}
Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/TestWebServer.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/TestWebServer.java?rev=1521521&r1=1521520&r2=1521521&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/TestWebServer.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/TestWebServer.java Tue Sep 10 15:14:46 2013
@@ -42,85 +42,51 @@ import org.eclipse.jetty.servlet.Servlet
import org.eclipse.jetty.servlet.ServletHolder;
/**
- * Test utility that manages a Jetty webserver with a {@link DefaultServlet} that support HTTP range downloads and a simple
- * HTTP protocol dump filter. It can be extended with custom test servlets.
+ * Test utility that manages a Jetty webserver with a {@link DefaultServlet} that support HTTP range downloads and a
+ * simple HTTP protocol dump filter. It can be extended with custom test servlets.
*/
public class TestWebServer {
- private Server m_server;
- private ServletContextHandler m_contextHandler;
-
- public TestWebServer(int port, String contextPath, String basePath) throws Exception {
-
- m_server = new Server(port);
-
- m_contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
- m_contextHandler.setContextPath("/");
-
- ServletHolder holder = new ServletHolder(new DefaultServlet());
- holder.setInitParameter("resourceBase", basePath);
- holder.setInitParameter("pathInfoOnly", "true");
- holder.setInitParameter("acceptRanges", "true");
- holder.setInitParameter("dirAllowed", "true");
-
- m_contextHandler.addFilter(new FilterHolder(new HttpDumpFilter()), "/*", null);
- m_contextHandler.addServlet(holder, contextPath.concat(contextPath.endsWith("/") ? "*" : "/*"));
- m_server.setHandler(m_contextHandler);
- }
-
- public void start() throws Exception {
- m_server.start();
- }
-
- public void stop() throws Exception {
- m_server.stop();
- m_server.join();
- }
-
- public void addServlet(Servlet servlet, String pathPsec) {
- m_contextHandler.addServlet(new ServletHolder(servlet), pathPsec);
- }
-
static class HttpDumpFilter implements Filter {
-
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- }
-
@Override
public void destroy() {
+ // Nop
}
@Override
+ @SuppressWarnings("unchecked")
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest hreq = (HttpServletRequest) req;
HttpServletResponse hres = (HttpServletResponse) res;
- @SuppressWarnings("unchecked")
+ ResponseInfoCollector coll = new ResponseInfoCollector(hres);
+ chain.doFilter(req, coll);
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("> ").append(hreq.getMethod()).append(" ").append(hreq.getRequestURI()).append(" ").append(req.getProtocol()).append('\n');
Enumeration<String> attrs = hreq.getHeaderNames();
- System.out.println("> " + hreq.getMethod() + " " + hreq.getRequestURI() + " " + req.getProtocol());
while (attrs.hasMoreElements()) {
String attr = attrs.nextElement();
- System.out.println("> " + attr + ":" + hreq.getHeader(attr));
+ sb.append("> ").append(attr).append(": ").append(hreq.getHeader(attr)).append('\n');
}
- ResponseInfoCollector coll = new ResponseInfoCollector(hres);
- chain.doFilter(req, coll);
- // servlet API 3.0
- // System.out.println("< " + res.getStatus());
- // for (String headerName : res.getHeaderNames())
- // System.out.println("< " + headerName + ":" + res.getHeader(headerName));
- System.out.println("< " + coll.statusCode + " " + coll.statusMessage);
+ sb.append("< ").append(hreq.getProtocol()).append(" ").append(coll.statusCode).append(" ").append(coll.statusMessage).append('\n');
for (String headerName : coll.headers.keySet()) {
- System.out.println("< " + headerName + ":" + coll.headers.get(headerName));
+ sb.append("< ").append(headerName).append(": ").append(coll.headers.get(headerName)).append('\n');
}
+
+ System.out.println(sb);
+ }
+
+ @Override
+ public void init(FilterConfig config) throws ServletException {
+ // Nop
}
}
static class ResponseInfoCollector extends HttpServletResponseWrapper {
-
long statusCode;
- String statusMessage;
+ String statusMessage = "";
Map<String, String> headers = new HashMap<String, String>();
public ResponseInfoCollector(HttpServletResponse response) {
@@ -128,9 +94,16 @@ public class TestWebServer {
}
@Override
- public void setHeader(String name, String value) {
- headers.put(name, value);
- super.setHeader(name, value);
+ public void sendError(int sc) throws IOException {
+ statusCode = sc;
+ super.sendError(sc);
+ }
+
+ @Override
+ public void sendError(int sc, String msg) throws IOException {
+ statusCode = sc;
+ statusMessage = msg;
+ super.sendError(sc, msg);
}
@Override
@@ -140,22 +113,61 @@ public class TestWebServer {
}
@Override
+ public void setHeader(String name, String value) {
+ headers.put(name, value);
+ super.setHeader(name, value);
+ }
+
+ @Override
public void setIntHeader(String name, int value) {
headers.put(name, "" + value);
super.setIntHeader(name, value);
}
@Override
- public void setStatus(int sc, String sm) {
+ public void setStatus(int sc) {
statusCode = sc;
- statusMessage = sm;
- super.setStatus(sc, sm);
+ super.setStatus(sc);
}
@Override
- public void setStatus(int sc) {
+ public void setStatus(int sc, String sm) {
statusCode = sc;
- super.setStatus(sc);
+ statusMessage = sm;
+ super.setStatus(sc, sm);
}
}
+
+ private final ServletContextHandler m_contextHandler;
+ private final Server m_server;
+
+ public TestWebServer(int port, String contextPath, String basePath) throws Exception {
+ m_server = new Server(port);
+
+ m_contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ m_contextHandler.setContextPath("/");
+
+ ServletHolder holder = new ServletHolder(new DefaultServlet());
+ holder.setInitParameter("resourceBase", basePath);
+ holder.setInitParameter("pathInfoOnly", "true");
+ holder.setInitParameter("acceptRanges", "true");
+ holder.setInitParameter("dirAllowed", "true");
+
+ m_contextHandler.addFilter(new FilterHolder(new HttpDumpFilter()), "/*", null);
+ m_contextHandler.addServlet(holder, contextPath.concat(contextPath.endsWith("/") ? "*" : "/*"));
+ m_server.setHandler(m_contextHandler);
+ }
+
+ public void addServlet(Servlet servlet, String pathPsec) {
+ m_contextHandler.addServlet(new ServletHolder(servlet), pathPsec);
+ }
+
+ public void start() throws Exception {
+ m_server.start();
+ }
+
+ public void stop() throws Exception {
+ m_server.stop();
+ m_server.join();
+ }
}