Make webapp single page (only Ajax)

This commit is contained in:
Dave Syer
2011-04-27 13:15:10 +01:00
parent 33c47b2df0
commit 5d22672564
6 changed files with 122 additions and 107 deletions

View File

@@ -24,18 +24,22 @@ import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.log4j.converter.AmqpLogMessageConverter;
import org.springframework.amqp.rabbit.log4j.listener.AmqpLogMessageConverter;
import org.springframework.amqp.rabbit.log4j.listener.AmqpLogMessageListener;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Configuration for Server.
*
* @author Tomas Lukosius
* @author Dave Syer
*/
@Configuration
@Import(PropertyPlaceholderConfiguration.class)
public class RabbitServerConfiguration {
/**
@@ -45,22 +49,31 @@ public class RabbitServerConfiguration {
public static String LOG_QUEUE_NAME = "app.log4j.demo";
public static String LOG_ALL_INFO_ROUTING_KEY = "#." + Level.INFO.toString();
@Value("${amqp.port:5672}")
private int port = 5672;
@Value("${amqp.username:guest}")
private String username = "guest";
@Value("${amqp.password:guest}")
private String password = "guest";
@Value("${amqp.vhost:/}")
private String virtualHost = "/";
@Value("${amqp.host:localhost}")
private String host = "localhost";
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setPort(port);
return connectionFactory;
}
@Bean
public MessageConverter amqpLogMessageConverter() {
return new AmqpLogMessageConverter();
}
@Bean
public TopicExchange logExchange() {
return new TopicExchange(LOG_EXCHANGE_NAME, false, false);
@@ -83,7 +96,7 @@ public class RabbitServerConfiguration {
@Bean
public Binding binding() {
return BindingBuilder.from(queue()).to(logExchange()).with(LOG_ALL_INFO_ROUTING_KEY);
return BindingBuilder.bind(queue()).to(logExchange()).with(LOG_ALL_INFO_ROUTING_KEY);
}
@Bean
@@ -105,3 +118,15 @@ public class RabbitServerConfiguration {
return container;
}
}
/**
* Configuration for property placeholders (enables system and OS placeholders with <code>&#64;Value(${...})</code>).
* @author Dave Syer
*/
@Configuration
class PropertyPlaceholderConfiguration {
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertyPlaceholderConfigurer();
}
}

View File

@@ -10,7 +10,7 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.amqp.rabbit.log4j.web.domain;
package org.springframework.amqp.rabbit.log4j.listener;
import java.text.DateFormat;
import java.util.Date;

View File

@@ -10,7 +10,7 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.amqp.rabbit.log4j.converter;
package org.springframework.amqp.rabbit.log4j.listener;
import java.util.Date;
import java.util.Map;
@@ -20,7 +20,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.log4j.AmqpAppender;
import org.springframework.amqp.rabbit.log4j.web.domain.AmqpLogMessage;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.util.CollectionUtils;

View File

@@ -17,7 +17,6 @@ import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.PriorityBlockingQueue;
import org.springframework.amqp.rabbit.log4j.web.domain.AmqpLogMessage;
/**
* @author tomas.lukosius@opencredo.com

View File

@@ -16,8 +16,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.Binding;
@@ -25,29 +23,27 @@ import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.log4j.config.server.RabbitServerConfiguration;
import org.springframework.amqp.rabbit.log4j.listener.AmqpLogMessage;
import org.springframework.amqp.rabbit.log4j.listener.AmqpLogMessageListener;
import org.springframework.amqp.rabbit.log4j.web.domain.AmqpLogMessage;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author tomas.lukosius@opencredo.com
* @author Tomas Lukosius
* @author Dave Syer
*
*/
@Controller
public class LogsController implements DisposableBean {
protected Log logger = LogFactory.getLog(this.getClass());
private static final String CURRENT_LOG_QUEUE = "CURRENT_LOG_QUEUE";
private static final String CURRENT_ROUTINGKEY = "CURRENT_ROUTINGKEY";
@Autowired
private TopicExchange exchange;
@@ -63,12 +59,9 @@ public class LogsController implements DisposableBean {
@Autowired
private AmqpLogMessageListener messageListener;
@RequestMapping("/logs")
@RequestMapping(value="/logs", method=RequestMethod.GET)
@ResponseBody
public List<AmqpLogMessage> logs(@RequestParam(required = false) Long timestamp, HttpSession session) {
session.setAttribute(CURRENT_LOG_QUEUE, RabbitServerConfiguration.LOG_QUEUE_NAME);
session.setAttribute(CURRENT_ROUTINGKEY, binding.getRoutingKey());
public List<AmqpLogMessage> logs(@RequestParam(required = false) Long timestamp) {
if (timestamp == null) {
timestamp = 0L;
}
@@ -82,26 +75,26 @@ public class LogsController implements DisposableBean {
return list;
}
@RequestMapping("/bindQueue")
@RequestMapping(value="/binding", method=RequestMethod.POST)
@ResponseBody
public String addQueue(@RequestParam(required = true, value = "routingkey") String routingKey, HttpSession session) {
if (!StringUtils.hasText(routingKey)) {
return "Routing key expected";
}
public Binding addBinding(@RequestParam String routingKey) {
try {
admin.removeBinding(binding);
binding = BindingBuilder.from(logQueue).to(exchange).with(routingKey);
Binding binding = BindingBuilder.bind(logQueue).to(exchange).with(routingKey);
admin.declareBinding(binding);
this.binding = binding;
} catch (RuntimeException e) {
// TODO: create a new BindingResult object to carry back error message
logger.error("Failed to declare queue or bind it with exchage", e);
return e.getMessage();
}
session.setAttribute(CURRENT_LOG_QUEUE, RabbitServerConfiguration.LOG_QUEUE_NAME);
session.setAttribute(CURRENT_ROUTINGKEY, binding.getRoutingKey());
return this.binding;
}
return "Queue '" + logQueue.getName() + "' was binded with routing key '" + routingKey + "'";
@RequestMapping(value="/binding", method=RequestMethod.GET)
@ResponseBody
public Binding getBinding() {
return binding;
}
public void destroy() throws Exception {

View File

@@ -83,6 +83,16 @@
$('#stop').click(stop);
$('#clear').click(clear);
start();
$.get($('#bindQueueForm').attr("action"), null, function(response) {
if (response) {
$('#queueName').text(response.destination);
$('#bindingMessages').text("Queue '"+response.destination+"' is bound with routing key '"+response.routingKey+"'");
$('#routingKey').val(response.routingKey);
} else {
$('#bindingMessages').text(
"The binding properties could not be determined at this time.");
}
});
$('#logAForm')
.submit(
function() {
@@ -92,8 +102,8 @@
$('#logAForm').serialize(),
function(response) {
if (response) {
$('#messages')
.text(response);
$('#messages').text(
response);
} else {
$('#messages')
.text(
@@ -111,8 +121,8 @@
$('#logBForm').serialize(),
function(response) {
if (response) {
$('#messages')
.text(response);
$('#messages').text(
response);
} else {
$('#messages')
.text(
@@ -121,44 +131,37 @@
});
return false;
});
$('#randomLogForm')
$('#randomLogForm').submit(
function() {
$.post($('#randomLogForm').attr("action"), $(
'#randomLogForm').serialize(), function(response) {
if (response) {
$('#messages').text(response);
} else {
$('#messages').text(
"The random log request failed.");
}
});
return false;
});
$('#bindQueueForm')
.submit(
function() {
$
.post(
$('#randomLogForm').attr("action"),
$('#randomLogForm').serialize(),
$('#bindQueueForm').attr("action"),
$('#bindQueueForm').serialize(),
function(response) {
if (response) {
$('#messages')
.text(response);
$('#bindingMessages').text("Queue '"+response.destination+"' is bound with routing key '"+response.routingKey+"'");
} else {
$('#messages')
$('#bindingMessages')
.text(
"The random log request failed.");
"The bind queue request was invalid. Please provide a not empty queue and routing key.");
}
});
return false;
});
$('#bindQueueForm')
.submit(
function() {
$
.post(
$('#bindQueueForm').attr("action"),
$('#bindQueueForm').serialize(),
function(response) {
if (response) {
$('#messages')
.text(response);
} else {
$('#messages')
.text(
"The bind queue request was invalid. Please provide a not empty queue and routing key.");
}
});
return false;
});
});
</script>
</head>
@@ -195,7 +198,7 @@
<c:set var="messageB" value="Manual log message [B]" />
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="randomLogCount!=null">
<c:set var="randomLogCount" value="${randomLogCount}" />
@@ -204,31 +207,25 @@
<c:set var="randomLogCount" value="10" />
</c:otherwise>
</c:choose>
<c:set var="routingKey" value="${CURRENT_ROUTINGKEY}" />
<div id="content" class="no-side-nav">
This application is a the "log4j" sample from <a
href="http://github.com/SpringSource/spring-amqp">Spring AMQP</a>.
You can get the source code from the <a
href="http://github.com/SpringSource/spring-amqp-samples">Spring
AMQP Samples</a> project on Github.
AMQP Samples</a> project on Github.
<h1>
Routing key for queue '
<c:out value="${CURRENT_LOG_QUEUE}" />
'
</h1>
<form id="bindQueueForm" method="post" action="bindQueue">
<h1 id="routingHeader">Routing Key</h1>
<form id="bindQueueForm" method="post" action="binding">
<ol>
<li><label for="bindQueue">Routing key</label><input
id="routingkey" type="text" name="routingkey" value="${routingKey}"/>
</li>
<li><label for="routingKey">Routing key</label><input
id="routingKey" type="text" name="routingKey" value="" /></li>
<li><label for="bindQueue">Submit new routing key</label><input
type="submit" name="bindQueue" value="Submit" /></li>
id="bindQueue" type="submit" name="bindQueue" value="Submit" />
</li>
</ol>
</form>
<div id="bindingMessages"></div>
<br /> <br />
<table class="bordered-table">
<thead>
@@ -248,14 +245,17 @@
<option value="debug">debug</option>
<option value="warn">warn</option>
<option value="error">error</option>
</select></li>
</select>
</li>
<li><label for="messageA">Log message</label><input
id="messageA" type="text" name="message" value="${messageA}" />
</li>
<li><label for="messageA">Submit log message</label><input
type="submit" name="logA" value="Submit" /></li>
type="submit" name="logA" value="Submit" />
</li>
</ol>
</form></td>
</form>
</td>
<td>
<form id="logBForm" method="post" action="logB">
<ol>
@@ -265,29 +265,32 @@
<option value="debug">debug</option>
<option value="warn">warn</option>
<option value="error">error</option>
</select></li>
</select>
</li>
<li><label for="messageB">Log message</label><input
id="messageB" type="text" name="message" value="${messageB}" />
</li>
<li><label for="messageB">Submit log message</label><input
type="submit" name="logB" value="Submit" /></li>
</ol>
</form></td>
</tr>
<tr>
<td colspan="2">
<h1>Random log generation</h1>
<form id="randomLogForm" method="post" action="randomLog">
<ol>
<li><label for="randomLog">Log count</label><input
id="randomLog" type="text" name="count" value="${randomLogCount}" />
type="submit" name="logB" value="Submit" />
</li>
<li><label for="randomLog">Submit to generate logs</label><input
type="submit" name="randomLog" value="Submit" /></li>
</ol>
</form>
</td>
</tr>
<tr>
<td colspan="2">
<h1>Random log generation</h1>
<form id="randomLogForm" method="post" action="randomLog">
<ol>
<li><label for="randomLog">Log count</label><input
id="randomLog" type="text" name="count"
value="${randomLogCount}" /></li>
<li><label for="randomLog">Submit to generate
logs</label><input type="submit" name="randomLog" value="Submit" />
</li>
</ol>
</form></td>
</tr>
</tbody>
</table>
@@ -295,11 +298,7 @@
<div id="messages">
<form:errors path="*" cssClass="errors" />
</div>
<h1>
Logs from queue '
<c:out value="${CURRENT_LOG_QUEUE}" />
'
</h1>
<h1 id="logs-header">Logs from queue '<span id="queueName"></span>'</h1>
<div id="status">Stopped</div>
<br />
<button id="start">Start</button>