summaryrefslogtreecommitdiff
path: root/java/broker/src
diff options
context:
space:
mode:
authorMartin Ritchie <ritchiem@apache.org>2009-07-24 11:32:40 +0000
committerMartin Ritchie <ritchiem@apache.org>2009-07-24 11:32:40 +0000
commit4216f29cf38e35f4ab764c11a8374bc55a8ae2cf (patch)
tree6ad7dbff44550b9428f7bd7a0fc34b251c8eb157 /java/broker/src
parent6bed8ffff53f1006eee53bf25a90329f9096bdea (diff)
downloadqpid-python-4216f29cf38e35f4ab764c11a8374bc55a8ae2cf.tar.gz
QPID-2001 : Update to provide control of options in messages.
Update to improve formatting of generated code Inclusion of more documentation Defaulted generation to use US locale Removed duplicate messages in MST that were added to while the option solution was being discussed. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@797421 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker/src')
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/messages/LogMessages_en_US.properties212
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java21
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/BindingMessagesTest.java16
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/ConnectionMessagesTest.java17
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java23
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/MessageStoreMessagesTest.java26
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/QueueMessagesTest.java106
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/SubscriptionMessagesTest.java30
-rw-r--r--java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java244
-rw-r--r--java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm95
10 files changed, 675 insertions, 115 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/LogMessages_en_US.properties b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/LogMessages_en_US.properties
index d393614191..8e9ee3720c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/LogMessages_en_US.properties
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/LogMessages_en_US.properties
@@ -1,13 +1,198 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# LogMessages used within the Java Broker as originally defined on the wiki:
+#
+# http://cwiki.apache.org/confluence/display/qpid/Status+Update+Design#StatusUpdateDesign-InitialStatusMessages
+#
+# Technical Notes:
+# This is a standard Java Properties file so white space is respected at the
+# end of the lines. This file is processed in a number of ways.
+# 1) ResourceBundle
+# This file is loaded through a ResourceBundle named LogMessages. the en_US
+# addition to the file is the localisation. Additional localisations can be
+# provided and will automatically be selected based on the <locale> value in
+# the config.xml. The default is en_US.
+#
+# 2) MessasgeFormat
+# Each entry is prepared with the Java Core MessageFormat methods. Therefore
+# most functionality you can do via MessageFormat can be done here:
+#
+# http://java.sun.com/javase/6/docs/api/java/text/MessageFormat.html
+#
+# The cavet here is that only default String and number FormatTypes can be used.
+# This is due to the processing described in 3 below. If support for date, time
+# or choice is requried then the GenerateLogMessages class should be updated to
+# provide support.
+#
+# Format Note:
+# As mentioned earlier white space in this file is very important. One thing
+# in particular to note is the way MessageFormat peforms its replacements.
+# The replacement text will totally replace the {xxx} section so there will be
+# no addtion of white space or removal e.g.
+# MSG = Text----{0}----
+# When given parameter 'Hello' result in text:
+# Text----Hello----
+#
+# For simple arguments this is expected however when using Style formats then
+# it can be a little unexepcted. In particular a common pattern is used for
+# number replacements : {0,number,#}. This is used in the Broker to display an
+# Integer simply as the Integer with no formating. e.g new Integer(1234567)
+# becomes the String "1234567" which is can be contrasted with the pattern
+# without a style format field : {0,number} which becomes string "1,234,567".
+#
+# What you may not expect is that {0,number, #} would produce the String " 1234567"
+# note the space after the ',' here /\ has resulted in a space /\ in
+# the output.
+#
+# More details on the SubformatPattern can be found on the API link above.
+#
+# 3) GenerateLogMessage/Velocity Macro
+# This is the first and final stage of processing that this file goes through.
+# 1) Class Generation:
+# The GenerateLogMessage processes this file and uses the velocity Macro
+# to create classes with static methods to perform the logging and give us
+# compile time validation.
+#
+# 2) Property Processing:
+# During the class generation the message properties ({x}) are identified
+# and used to create the method signature.
+#
+# 3) Option Processing:
+# The Classes perform final formatting of the messages at runtime based on
+# optional parameters that are defined within the message. Optional
+# paramters are enclosed in square brackets e.g. [optional].
+#
+# To provide fixed log messages as required by the Technical Specification:
+# http://cwiki.apache.org/confluence/display/qpid/Operational+Logging+-+Status+Update+-+Technical+Specification#OperationalLogging-StatusUpdate-TechnicalSpecification-Howtoprovidefixedlogmessages
+#
+# This file is processed by Velocity to create a number of classes that contain
+# static methods that provide LogMessages in the code to provide compile time
+# validation.
+#
+# For details of what processing is done see GenerateLogMessages.
+#
+# What a localiser or developer need know is the following:
+#
+# The Property structure is important is it defines how the class and methods
+# will be built.
+#
+# Class Generation:
+# =================
+#
+# Each class of messages will be split in to their own <Class>Messages.java
+# Currently the following classes are created and are populated with the
+# messages that bear their 3-digit type identifier:
+#
+# Class | Type
+# ---------------------|--------
+# Broker | BKR
+# ManagementConsole | MNG
+# VirtualHost | VHT
+# MessageStore | MST
+# Connection | CON
+# Channel | CHN
+# Queue | QUE
+# Exchange | EXH
+# Binding | BND
+# Subscription | SUB
+#
+# Property Processing:
+# ====================
+#
+# Each property is then processed by the GenerateLogMessages class to identify
+# The number and type of parameters, {x} entries. Parameters are defaulted to
+# String types but the use of FormatType number (e.g.{0,number}) will result
+# in a Number type being used. These parameters are then used to build the
+# method parameter list. e.g:
+# Property:
+# BRK-1003 = Shuting down : {0} port {1,number,#}
+# becomes Method:
+# public static LogMessage BRK_1003(String param1, Number param2)
+#
+# This improves our compile time validation of log message content and
+# ensures that change in the message format does not accidentally cause
+# erroneous messages.
+#
+# Option Processing:
+# ====================
+#
+# Options are identified in the log message as being surrounded by square
+# brackets ([ ]). These optional values can themselves contain paramters
+# however nesting of options is not permitted. Identification is performed on
+# first matchings so give the message:
+# Msg = Log Message [option1] [option2]
+# Two options will be identifed and enabled to select text 'option1 and
+# 'option2'.
+#
+# The nesting of a options is not supported and will provide
+# unexpected results. e.g. Using Message:
+# Msg = Log Message [option1 [sub-option2]]
+#
+# The options will be 'option1 [sub-option2' and 'sub-option2'. The first
+# option includes the second option as the nesting is not detected.
+#
+# The detected options are presented in the method signature as boolean options
+# numerically identified by their position in the message. e.g.
+# Property:
+# CON-1001 = Open : Client ID {0} [: Protocol Version : {1}]
+# becomes Method:
+# public static LogMessage CON_1001(String param1, String param2, boolean opt1)
+#
+# The value of 'opt1' will show/hide the option in the message. Note that
+# 'param2' is still required however a null value can be used if the optional
+# section is not desired.
+#
+# Again here the importance of white space needs to be highlighted.
+# Looking at the QUE-1001 message as an example. The first thought on how this
+# would look would be as follows:
+# QUE-1001 = Create : Owner: {0} [AutoDelete] [Durable] [Transient] [Priority: {1,number,#}]
+# Each option is correctly defined so the text that is defined will appear when
+# selected. e.g. 'AutoDelete'. However, what may not be immediately apparent is
+# the white space. Using the above definition of QUE-1001 if we were to print
+# the message with only the Priority option displayed it would appear as this:
+# "Create : Owner: guest Priority: 1"
+# Note the spaces here /\ This is because only the text between the brackets
+# has been removed.
+#
+# Each option needs to include white space to correctly format the message. So
+# the correct definition of QUE-1001 is as follows:
+# QUE-1001 = Create : Owner: {0}[ AutoDelete][ Durable][ Transient][ Priority: {1,number,#}]
+# Note that white space is included with each option and there is no extra
+# white space between the options. As a result the output with just Priority
+# enabled is as follows:
+# "Create : Owner: guest Priority: 1"
+#
+# The final processing that is done in the generation is the conversion of the
+# property name. As a '-' is an illegal character in the method name it is
+# converted to '_' This processing gives the final method signature as follows:
+# <Class>Message.<Type>_<Number>(<parmaters>,<options>)
+#
#Broker
# 0 - Version
# 1 = Build
BRK-1001 = Startup : Version: {0} Build: {1}
# 0 - Transport
# 1 - Port
-BRK-1002 = Starting : Listening on {0} port {1, number, #}
+BRK-1002 = Starting : Listening on {0} port {1,number,#}
# 0 - Transport
# 1 - Port
-BRK-1003 = Shuting down : {0} port {1, number, #}
+BRK-1003 = Shuting down : {0} port {1,number,#}
BRK-1004 = Ready
BRK-1005 = Stopped
# 0 - path
@@ -19,10 +204,10 @@ BRK-1007 = Using logging configuration : {0}
MNG-1001 = Startup
# 0 - Service
# 1 - Port
-MNG-1002 = Starting : {0} : Listening on port {1, number, #}
+MNG-1002 = Starting : {0} : Listening on port {1,number,#}
# 0 - Service
# 1 - Port
-MNG-1003 = Shuting down : {0} : port {1, number, #}
+MNG-1003 = Shuting down : {0} : port {1,number,#}
MNG-1004 = Ready
MNG-1005 = Stopped
# 0 - Path
@@ -39,20 +224,18 @@ MST-1001 = Created : {0}
# 0 - path
MST-1002 = Store location : {0}
MST-1003 = Closed
-MST-1004 = Recovery Start
# 0 - queue name
-MST-1005 = Recovery Start : {0}
+MST-1004 = Recovery Start[ : {0}]
# 0 - count
# 1 - queue count
-MST-1006 = Recovered {0,number} messages for queue {1}
-MST-1007 = Recovery Complete
+MST-1005 = Recovered {0,number} messages for queue {1}
# 0 - queue name
-MST-1008 = Recovery Complete : {0}
+MST-1006 = Recovery Complete[ : {0}]
#Connection
# 0 - Client id
# 1 - Protocol Version
-CON-1001 = Open : Client ID {0} : Protocol Version : {1}
+CON-1001 = Open : Client ID {0}[ : Protocol Version : {1}]
CON-1002 = Close
#Channel
@@ -64,19 +247,20 @@ CHN-1003 = Close
#Queue
# 0 - owner
-QUE-1001 = Create : Owner:{0} [AutoDelete] [Durable|Transient] [Priority:<levels>]
+# 1 - priority
+QUE-1001 = Create : Owner: {0}[ AutoDelete][ Durable][ Transient][ Priority: {1,number,#}]
QUE-1002 = Deleted
#Exchange
# 0 - type
# 1 - name
-EXH-1001 = Create : [Durable] Type:{0} Name:{1}
+EXH-1001 = Create :[ Durable] Type: {0} Name: {1}
EXH-1002 = Deleted
#Binding
-BND-1001 = Create [: Arguments : <key=value>]
+BND-1001 = Create[ : Arguments : {0}]
BND-1002 = Deleted
#Subscription
-SUB-1001 = Create : [Durable] [Arguments : <key=value>]
+SUB-1001 = Create[ : Durable][ : Arguments : {0}]
SUB-1002 = Close
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java
index 6589695146..17a9d6c591 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java
@@ -81,24 +81,35 @@ public abstract class AbstractTestMessages extends TestCase
{
assertEquals("Log has incorrect message count", 1, logs.size());
- String log = String.valueOf(logs.get(0));
+ //We trim() here as we don't care about extra white space at the end of the log message
+ // but we do care about the ability to easily check we don't have unexpected text at
+ // the end.
+ String log = String.valueOf(logs.get(0)).trim();
- int index = log.indexOf(_logSubject.toString());
+ // Simple switch to print out all the logged messages
+ //System.err.println(log);
- assertTrue("Unable to locate Subject:" + log, index != -1);
+ int msgIndex = log.indexOf(_logSubject.toString())+_logSubject.toString().length();
- String message = log.substring(index + _logSubject.toString().length());
+ assertTrue("Unable to locate Subject:" + log, msgIndex != -1);
+
+ String message = log.substring(msgIndex);
assertTrue("Message does not start with tag:" + tag + ":" + message,
message.startsWith(tag));
// Test that the expected items occur in order.
- index = 0;
+ int index = 0;
for (String text : expected)
{
index = message.indexOf(text, index);
assertTrue("Message does not contain expected (" + text + ") text :" + message, index != -1);
+ index = index + text.length();
}
+
+ //Check there is nothing left on the log message
+ assertEquals("Message has more text. '" + log.substring(msgIndex + index) + "'",
+ log.length(), msgIndex + index);
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BindingMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BindingMessagesTest.java
index a12d14239d..b2182bb1b2 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BindingMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BindingMessagesTest.java
@@ -25,9 +25,9 @@ import java.util.List;
public class BindingMessagesTest extends AbstractTestMessages
{
- public void testMessage1001()
+ public void testMessage1001_NoArgs()
{
- _logMessage = BindingMessages.BND_1001();
+ _logMessage = BindingMessages.BND_1001(null, false);
List<Object> log = performLog();
String[] expected = {"Create"};
@@ -35,6 +35,18 @@ public class BindingMessagesTest extends AbstractTestMessages
validateLogMessage(log, "BND-1001", expected);
}
+ public void testMessage1001_Args()
+ {
+ String arguments = "arguments";
+
+ _logMessage = BindingMessages.BND_1001(arguments, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create", ": Arguments :", arguments};
+
+ validateLogMessage(log, "BND-1001", expected);
+ }
+
public void testMessage1002()
{
_logMessage = BindingMessages.BND_1002();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ConnectionMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ConnectionMessagesTest.java
index 8723c48476..eb76029a5c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ConnectionMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ConnectionMessagesTest.java
@@ -24,12 +24,12 @@ import java.util.List;
public class ConnectionMessagesTest extends AbstractTestMessages
{
- public void testMessage1001()
+ public void testMessage1001_WithProtocolVersion()
{
String clientID = "client";
String protocolVersion = "8-0";
- _logMessage = ConnectionMessages.CON_1001(clientID, protocolVersion);
+ _logMessage = ConnectionMessages.CON_1001(clientID, protocolVersion, true);
List<Object> log = performLog();
String[] expected = {"Open :", "Client ID", clientID,
@@ -38,6 +38,19 @@ public class ConnectionMessagesTest extends AbstractTestMessages
validateLogMessage(log, "CON-1001", expected);
}
+ public void testMessage1001_NoProtocolVersion()
+ {
+ String clientID = "client";
+
+ _logMessage = ConnectionMessages.CON_1001(clientID, null, false);
+ List<Object> log = performLog();
+
+ String[] expected = {"Open :", "Client ID", clientID};
+
+ validateLogMessage(log, "CON-1001", expected);
+ }
+
+
public void testMessage1002()
{
_logMessage = ConnectionMessages.CON_1002();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
index 46a911fdc6..831ede3e0c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
@@ -27,7 +27,7 @@ import java.util.List;
public class ExchangeMessagesTest extends AbstractTestMessages
{
- public void testMessage1001()
+ public void testMessage1001_Transient()
{
// Get the Default Exchange on the Test Vhost for testing
Exchange exchange = ApplicationRegistry.getInstance().
@@ -37,7 +37,7 @@ public class ExchangeMessagesTest extends AbstractTestMessages
String type = exchange.getType().toString();
String name = exchange.getName().toString();
- _logMessage = ExchangeMessages.EXH_1001(type, name);
+ _logMessage = ExchangeMessages.EXH_1001(type, name, false);
List<Object> log = performLog();
String[] expected = {"Create :", "Type:", type, "Name:", name};
@@ -45,6 +45,25 @@ public class ExchangeMessagesTest extends AbstractTestMessages
validateLogMessage(log, "EXH-1001", expected);
}
+ public void testMessage1001_Persistent()
+ {
+ // Get the Default Exchange on the Test Vhost for testing
+ Exchange exchange = ApplicationRegistry.getInstance().
+ getVirtualHostRegistry().getVirtualHost("test").
+ getExchangeRegistry().getDefaultExchange();
+
+ String type = exchange.getType().toString();
+ String name = exchange.getName().toString();
+
+ _logMessage = ExchangeMessages.EXH_1001(type, name, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Durable", "Type:", type, "Name:", name};
+
+ validateLogMessage(log, "EXH-1001", expected);
+ }
+
+
public void testMessage1002()
{
_logMessage = ExchangeMessages.EXH_1002();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/MessageStoreMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/MessageStoreMessagesTest.java
index e1ae93b869..e02993b840 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/MessageStoreMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/MessageStoreMessagesTest.java
@@ -61,7 +61,7 @@ public class MessageStoreMessagesTest extends AbstractTestMessages
public void testMessage1004()
{
- _logMessage = MessageStoreMessages.MST_1004();
+ _logMessage = MessageStoreMessages.MST_1004(null,false);
List<Object> log = performLog();
String[] expected = {"Recovery Start"};
@@ -69,24 +69,24 @@ public class MessageStoreMessagesTest extends AbstractTestMessages
validateLogMessage(log, "MST-1004", expected);
}
- public void testMessage1005()
+ public void testMessage1004_withQueue()
{
String queueName = "testQueue";
- _logMessage = MessageStoreMessages.MST_1005(queueName);
+ _logMessage = MessageStoreMessages.MST_1004(queueName, true);
List<Object> log = performLog();
String[] expected = {"Recovery Start :", queueName};
- validateLogMessage(log, "MST-1005", expected);
+ validateLogMessage(log, "MST-1004", expected);
}
- public void testMessage1006()
+ public void testMessage1005()
{
String queueName = "testQueue";
Integer messasgeCount = 2000;
- _logMessage = MessageStoreMessages.MST_1006(messasgeCount, queueName);
+ _logMessage = MessageStoreMessages.MST_1005(messasgeCount, queueName);
List<Object> log = performLog();
// Here we use MessageFormat to ensure the messasgeCount of 2000 is
@@ -95,29 +95,29 @@ public class MessageStoreMessagesTest extends AbstractTestMessages
MessageFormat.format("{0,number}", messasgeCount),
"messages for queue", queueName};
- validateLogMessage(log, "MST-1006", expected);
+ validateLogMessage(log, "MST-1005", expected);
}
- public void testMessage1007()
+ public void testMessage1006()
{
- _logMessage = MessageStoreMessages.MST_1007();
+ _logMessage = MessageStoreMessages.MST_1006(null,false);
List<Object> log = performLog();
String[] expected = {"Recovery Complete"};
- validateLogMessage(log, "MST-1007", expected);
+ validateLogMessage(log, "MST-1006", expected);
}
- public void testMessage1008()
+ public void testMessage1006_withQueue()
{
String queueName = "testQueue";
- _logMessage = MessageStoreMessages.MST_1008(queueName);
+ _logMessage = MessageStoreMessages.MST_1006(queueName, true);
List<Object> log = performLog();
String[] expected = {"Recovery Complete :", queueName};
- validateLogMessage(log, "MST-1008", expected);
+ validateLogMessage(log, "MST-1006", expected);
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/QueueMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/QueueMessagesTest.java
index 4ba00ea6e4..2f53d0aff5 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/QueueMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/QueueMessagesTest.java
@@ -24,14 +24,114 @@ import java.util.List;
public class QueueMessagesTest extends AbstractTestMessages
{
- public void testMessage1001()
+ public void testMessage1001ALL()
{
String owner = "guest";
+ Integer priority = 3;
- _logMessage = QueueMessages.QUE_1001(owner);
+ _logMessage = QueueMessages.QUE_1001(owner, priority, true, true, true, true);
List<Object> log = performLog();
- String[] expected = {"Create :", "Owner:", owner};
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete",
+ "Durable", "Transient", "Priority:",
+ String.valueOf(priority)};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001AutoDelete()
+ {
+ String owner = "guest";
+
+ _logMessage = QueueMessages.QUE_1001(owner, null, true, false, false, false);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete"};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001Priority()
+ {
+ String owner = "guest";
+ Integer priority = 3;
+
+ _logMessage = QueueMessages.QUE_1001(owner, priority, false, false, false, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "Priority:",
+ String.valueOf(priority)};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001AutoDeletePriority()
+ {
+ String owner = "guest";
+ Integer priority = 3;
+
+ _logMessage = QueueMessages.QUE_1001(owner, priority, true, false, false, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete",
+ "Priority:",
+ String.valueOf(priority)};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001AutoDeleteTransient()
+ {
+ String owner = "guest";
+
+ _logMessage = QueueMessages.QUE_1001(owner, null, true, false, true, false);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete",
+ "Transient"};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001AutoDeleteTransientPriority()
+ {
+ String owner = "guest";
+ Integer priority = 3;
+
+ _logMessage = QueueMessages.QUE_1001(owner, priority, true, false, true, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete",
+ "Transient", "Priority:",
+ String.valueOf(priority)};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001AutoDeleteDurable()
+ {
+ String owner = "guest";
+
+ _logMessage = QueueMessages.QUE_1001(owner, null, true, true, false, false);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete",
+ "Durable"};
+
+ validateLogMessage(log, "QUE-1001", expected);
+ }
+
+ public void testMessage1001AutoDeleteDurablePriority()
+ {
+ String owner = "guest";
+ Integer priority = 3;
+
+ _logMessage = QueueMessages.QUE_1001(owner, priority, true, true, false, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Owner:", owner, "AutoDelete",
+ "Durable", "Priority:",
+ String.valueOf(priority)};
validateLogMessage(log, "QUE-1001", expected);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/SubscriptionMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/SubscriptionMessagesTest.java
index 1bb96e1e33..80ebcc79cd 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/SubscriptionMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/SubscriptionMessagesTest.java
@@ -24,17 +24,41 @@ import java.util.List;
public class SubscriptionMessagesTest extends AbstractTestMessages
{
- public void testMessage1001()
+ public void testMessage1001ALL()
{
+ String arguments = "arguments";
- _logMessage = SubscriptionMessages.SUB_1001();
+ _logMessage = SubscriptionMessages.SUB_1001(arguments, true, true);
List<Object> log = performLog();
- String[] expected = {"Create :"};
+ String[] expected = {"Create :", "Durable", "Arguments :", arguments};
validateLogMessage(log, "SUB-1001", expected);
}
+ public void testMessage1001Durable()
+ {
+ _logMessage = SubscriptionMessages.SUB_1001(null, true, false);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :", "Durable"};
+
+ validateLogMessage(log, "SUB-1001", expected);
+ }
+
+ public void testMessage1001Arguments()
+ {
+ String arguments = "arguments";
+
+ _logMessage = SubscriptionMessages.SUB_1001(arguments, false, true);
+ List<Object> log = performLog();
+
+ String[] expected = {"Create :","Arguments :", arguments};
+
+ validateLogMessage(log, "SUB-1001", expected);
+ }
+
+
public void testMessage1002()
{
_logMessage = SubscriptionMessages.SUB_1002();
diff --git a/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java b/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
index cc0565031f..ea0946f6d6 100644
--- a/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
+++ b/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
@@ -30,6 +30,7 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
@@ -210,15 +211,20 @@ public class GenerateLogMessages
* type checking during compilation whilst allowing the log message to
* maintain formatting controls.
*
+ * OPTIONS
+ *
* The returned hashMap contains the following structured data:
*
* - name - ClassName ('Broker')
- * list - methodName ('BRK_1001')
- * - name ('BRK-1001')
- * - format ('Startup : Version: {0} Build: {1}')
- * - parameters (list)
- * - type ('String'|'Number')
- * - name ('param1')
+ * - list[logEntryData] - methodName ('BRK_1001')
+ * - name ('BRK-1001')
+ * - format ('Startup : Version: {0} Build: {1}')
+ * - parameters (list)
+ * - type ('String'|'Number')
+ * - name ('param1')
+ * - options (list)
+ * - name ('opt1')
+ * - value ('AutoDelete')
*
* @param messsageName the name to give the Class e.g. 'Broker'
* @param messageKey the 3-digit key to extract the messages e.g. 'BRK'
@@ -228,7 +234,7 @@ public class GenerateLogMessages
private HashMap<String, Object> prepareType(String messsageName, String messageKey) throws InvalidTypeException
{
// Load the LogMessages Resource Bundle
- ResourceBundle _messages = ResourceBundle.getBundle("org.apache.qpid.server.logging.messages.LogMessages");
+ ResourceBundle _messages = ResourceBundle.getBundle("org.apache.qpid.server.logging.messages.LogMessages", Locale.US);
Enumeration<String> messageKeys = _messages.getKeys();
@@ -265,79 +271,187 @@ public class GenerateLogMessages
// Javadoc of the method.
logEntryData.put("format", logMessage);
- // Split the string on the start brace '{' this will give us the
- // details for each parameter that this message contains.
- String[] parametersString = logMessage.split("\\{");
- // Taking an example of 'Text {n[,type]} text {m} more text {p}'
- // This would give us:
- // 0 - Text
- // 1 - n[,type]} text
- // 2 - m} more text
- // 3 - p}
-
- // Create the parameter list for this item
- List<HashMap<String, String>> parameters = new LinkedList<HashMap<String, String>>();
+ // Add the parameters for this message
+ logEntryData.put("parameters", extractParameters(logMessage));
- // Add the parameter list to this log entry data
- logEntryData.put("parameters", parameters);
+ //Add the options for this messagse
+ logEntryData.put("options", extractOptions(logMessage));
- // Add the data to the list of messages
+ //Add this entry to the list for this class
logMessageList.add(logEntryData);
+ }
+ }
- // Check that we have some parameters to process
- // Skip 0 as that will not be the first entry
- // Text {n[,type]} text {m} more text {p}
- if (parametersString.length > 1)
- {
- for (int index = 1; index < parametersString.length; index++)
- {
- // Use a HashMap to store the type,name of the parameter
- // for easy retrieval in the macro template
- HashMap<String, String> parameter = new HashMap<String, String>();
+ return messageTypeData;
+ }
- // Check for any properties of the parameter :
- // e.g. {0} vs {0,number} vs {0,number,xxxx}
- int typeIndex = parametersString[index].indexOf(",");
+ /**
+ * This method is responsible for extracting the options form the given log
+ * message and providing a HashMap with the expected data:
+ * - options (list)
+ * - name ('opt1')
+ * - value ('AutoDelete')
+ *
+ * The options list that this method provides must contain HashMaps that
+ * have two entries. A 'name' and a 'value' these strings are important as
+ * they are used in LogMessage.vm to extract the stored String during
+ * processing of the template.
+ *
+ * The 'name' is a unique string that is used to name the boolean parameter
+ * and refer to it later in the method body.
+ *
+ * The 'value' is used to provide documentation in the generated class to
+ * aid readability.
+ *
+ * @param logMessage the message from the properties file
+ * @return list of option data
+ */
+ private List<HashMap<String, String>> extractOptions(String logMessage)
+ {
+ // Split the string on the start brace '{' this will give us the
+ // details for each parameter that this message contains.
+ // NOTE: Simply splitting on '[' prevents the use of nested options.
+ // Currently there is no demand for nested options
+ String[] optionString = logMessage.split("\\[");
+ // Taking an example of:
+ // 'Text {n,type,format} [option] text {m} [option with param{p}] more'
+ // This would give us:
+ // 0 - Text {n,type,format}
+ // 1 - option] text {m}
+ // 2 - option with param{p}] more
+
+ // Create the parameter list for this item
+ List<HashMap<String, String>> options = new LinkedList<HashMap<String, String>>();
+
+ // Check that we have some parameters to process
+ // Skip 0 as that will not be the first entry
+ // Text {n,type,format} [option] text {m} [option with param{p}] more
+ if (optionString.length > 1)
+ {
+ for (int index = 1; index < optionString.length; index++)
+ {
+ // Use a HashMap to store the type,name of the parameter
+ // for easy retrieval in the macro template
+ HashMap<String, String> option = new HashMap<String, String>();
- // The parameter type
- String type;
+ // Locate the end of the Option
+ // NOTE: it is this simple matching on the first ']' that
+ // prevents the nesting of options.
+ // Currently there is no demand for nested options
+ int end = optionString[index].indexOf("]");
- //Be default all types are Strings
- if (typeIndex == -1)
- {
- type = "String";
- }
- else
- {
- //Check string ',....}' for existence of number
- // to identify this parameter as an integer
- // This allows for a style value to be present
- // Only check the text inside the braces '{}'
- int typeIndexEnd = parametersString[index].indexOf("}", typeIndex);
- String typeString = parametersString[index].substring(typeIndex, typeIndexEnd);
- if (typeString.contains("number"))
- {
- type = "Number";
- }
- else
- {
- throw new InvalidTypeException("Invalid type(" + typeString + ") index (" + parameter.size() + ") in message:" + logMessage);
- }
+ // The parameter type
+ String value = optionString[index].substring(0, end);
- }
+ // Simply name the parameters by index.
+ option.put("name", "opt" + index);
+
+ //Store the value e.g. AutoDelete
+ // We trim as we don't need to include any whitespace that is
+ // used for formating. This is only used to aid readability of
+ // of the generated code.
+ option.put("value", value.trim());
- //Store the data
- parameter.put("type", type);
- // Simply name the parameters by index.
- parameter.put("name", "param" + index);
+ options.add(option);
+ }
+ }
- parameters.add(parameter);
+ return options;
+ }
+
+ /**
+ * This method is responsible for extract the parameters that are requried
+ * for this log message. The data is returned in a HashMap that has the
+ * following structure:
+ * - parameters (list)
+ * - type ('String'|'Number')
+ * - name ('param1')
+ *
+ * The parameters list that is provided must contain HashMaps that have the
+ * two named entries. A 'type' and a 'name' these strings are importans as
+ * they are used in LogMessage.vm to extract and the stored String during
+ * processing of the template
+ *
+ * The 'type' and 'name' values are used to populate the method signature.
+ * This is what gives us the compile time validation of log messages.
+ *
+ * The 'name' must be unique as there may be many parameters. The value is
+ * also used in the method body to pass the values through to the
+ * MessageFormat class for formating the log message.
+ *
+ * @param logMessage the message from the properties file
+ * @return list of option data
+ * @throws InvalidTypeException if the FormatType is specified and is not 'number'
+ */
+ private List<HashMap<String, String>> extractParameters(String logMessage)
+ throws InvalidTypeException
+ {
+ // Split the string on the start brace '{' this will give us the
+ // details for each parameter that this message contains.
+ String[] parametersString = logMessage.split("\\{");
+ // Taking an example of 'Text {n[,type]} text {m} more text {p}'
+ // This would give us:
+ // 0 - Text
+ // 1 - n[,type]} text
+ // 2 - m} more text
+ // 3 - p}
+
+ // Create the parameter list for this item
+ List<HashMap<String, String>> parameters = new LinkedList<HashMap<String, String>>();
+
+ // Check that we have some parameters to process
+ // Skip 0 as that will not be the first entry
+ // Text {n[,type]} text {m} more text {p}
+ if (parametersString.length > 1)
+ {
+ for (int index = 1; index < parametersString.length; index++)
+ {
+ // Use a HashMap to store the type,name of the parameter
+ // for easy retrieval in the macro template
+ HashMap<String, String> parameter = new HashMap<String, String>();
+
+ // Check for any properties of the parameter :
+ // e.g. {0} vs {0,number} vs {0,number,xxxx}
+ int typeIndex = parametersString[index].indexOf(",");
+
+
+ // The parameter type
+ String type;
+
+ //Be default all types are Strings
+ if (typeIndex == -1)
+ {
+ type = "String";
+ }
+ else
+ {
+ //Check string ',....}' for existence of number
+ // to identify this parameter as an integer
+ // This allows for a style value to be present
+ // Only check the text inside the braces '{}'
+ int typeIndexEnd = parametersString[index].indexOf("}", typeIndex);
+ String typeString = parametersString[index].substring(typeIndex, typeIndexEnd);
+ if (typeString.contains("number"))
+ {
+ type = "Number";
}
+ else
+ {
+ throw new InvalidTypeException("Invalid type(" + typeString + ") index (" + parameter.size() + ") in message:" + logMessage);
+ }
+
}
+
+ //Store the data
+ parameter.put("type", type);
+ // Simply name the parameters by index.
+ parameter.put("name", "param" + index);
+
+ parameters.add(parameter);
}
}
- return messageTypeData;
+ return parameters;
}
/**
diff --git a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm
index 6656763ab9..917901a18b 100644
--- a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm
+++ b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm
@@ -33,7 +33,10 @@ import java.util.ResourceBundle;
* This file is based on the content of LogMessages.properties
*
* It is generated so that we can provide compile time validation of the
- * message parameters
+ * message parameters.
+ *
+ * DO NOT EDIT DIRECTLY THIS FILE IS GENERATED.
+ *
*/
public class ${type.name}Messages
{
@@ -51,25 +54,105 @@ public class ${type.name}Messages
_formatter.setLocale(currentLocale);
}
+##
+## The list stored under key 'list' in the 'type' HashMap contains all the
+## log messages that this class should contain. So for each entry in the list
+## this template will create a new log method.
+##
#foreach( $message in ${type.list} )
/**
* Log a ${type.name} message of the Format:
- * <pre>${message.format}</pre>
+ * <pre>${message.format}</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
*/
+## There is a lot in the method header here. To make it more readable/understandable
+## This is the same text laid out to be easier to read:
+## public static LogMessage ${message.methodName} (
+## #foreach($parameter in ${message.parameters})
+## ${parameter.type} ${parameter.name}
+## #if (${velocityCount} != ${message.parameters.size()} )
+## ,
+## #end
+## #end
+## #if(${message.parameters.size()} > 0 && ${message.options.size()} > 0)
+## ,
+## #end
+## #foreach($option in ${message.options})
+## boolean ${option.name}
+## #if (${velocityCount} != ${message.options.size()} )
+## ,
+## #end
+## #end
+## )
+##
+## What is going on is that we set the method name based on the HashMap lookup
+## for 'methodName' Then for each entry(another HashMap) in the list stored
+## in the HashMap under 'parameters' build the argument list of from the 'type'
+## and 'name' values. Ensuring that we add a ', ' between each entry.
+##
+## However, check that we are not at the last entry of the list as we don't
+## want to add ', ' at then end.
+##
+## Before we go on to the options we perform a check to see if we had any
+## parameters. If we did and we have options to add then we add ', ' to keep
+## the syntax correct.
+##
+## We then go on to the options that are again retrieved from the top HashMap
+## with key 'options'. For each option a boolean argument is created and the
+## name is retrieved from the option HashMap with key 'name'
+##
public static LogMessage ${message.methodName}(#foreach($parameter in ${message.parameters})${parameter.type} ${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end
-#end)
+#end#if(${message.parameters.size()} > 0 && ${message.options.size()} > 0), #end#foreach($option in ${message.options})boolean ${option.name}#if (${velocityCount} != ${message.options.size()} ), #end#end)
{
final Object[] messageArguments = {#foreach($parameter in ${message.parameters})${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end#end};
-
_formatter.applyPattern(_messages.getString("${message.name}"));
+
+ ## If we have some options then we need to build the message based
+ ## on those values so only provide that logic if we need it.
+#if(${message.options.size()} > 0)
+ String rawMessage = _formatter.format(messageArguments);
+
+ StringBuffer msg =new StringBuffer("${message.name} : ");
+
+ // Split the formatted message up on the option values so we can
+ // rebuild the message based on the configured options.
+ String[] parts = rawMessage.split("\\[");
+ msg.append(parts[0]);
+
+ int end;
+ if (parts.length > 1)
+ {
+ ## For Each Optional value check if it has been enabled and then
+ ## append it to the log.
+#foreach($option in ${message.options})
+
+ // Add Option : ${option.value}
+ end = parts[${velocityCount}].indexOf(']');
+ if (${option.name})
+ {
+ msg.append(parts[${velocityCount}].substring(0, end));
+ }
+
+ // Use 'end + 1' to remove the ']' from the output
+ msg.append(parts[${velocityCount}].substring(end + 1));
+#end
+ }
+
+ final String message = msg.toString();
+#else
+ ## If we have no options then we can just format and set the log
+ final String message = "${message.name} : " + _formatter.format(messageArguments);
+#end
+
return new LogMessage()
{
public String toString()
{
- return "${message.name} : " + _formatter.format(messageArguments);
+ return message;
}
};
-
}
#end