Merge branch #62

This commit is contained in:
Martyn Taylor 2015-01-14 12:08:22 +00:00
commit 260f579c18
101 changed files with 2075 additions and 1726 deletions

View File

@ -48,6 +48,12 @@ public interface ClientSession extends XAResource, AutoCloseable
* Returns the names of the queues bound to the binding.
*/
List<SimpleString> getQueueNames();
/**
* Returns <code>true</code> if auto-creation for this address is enabled and if the address queried is for a JMS
* queue, <code>false</code> else.
*/
boolean isAutoCreateJmsQueues();
}
/**
@ -81,6 +87,12 @@ public interface ClientSession extends XAResource, AutoCloseable
*/
boolean isDurable();
/**
* Returns <code>true</code> if auto-creation for this queue is enabled and if the queue queried is a JMS queue,
* <code>false</code> else.
*/
boolean isAutoCreateJmsQueues();
/**
* Returns the number of consumers attached to the queue.
*/

View File

@ -565,7 +565,9 @@ public interface ActiveMQServerControl
@Parameter(desc = "the policy to use when the address is full", name = "addressFullMessagePolicy") String addressFullMessagePolicy,
@Parameter(desc = "when a consumer falls below this threshold in terms of messages consumed per second it will be considered 'slow'", name = "slowConsumerThreshold") long slowConsumerThreshold,
@Parameter(desc = "how often (in seconds) to check for slow consumers", name = "slowConsumerCheckPeriod") long slowConsumerCheckPeriod,
@Parameter(desc = "the policy to use when a slow consumer is detected", name = "slowConsumerPolicy") String slowConsumerPolicy) throws Exception;
@Parameter(desc = "the policy to use when a slow consumer is detected", name = "slowConsumerPolicy") String slowConsumerPolicy,
@Parameter(desc = "allow queues to be created automatically", name = "autoCreateJmsQueues") boolean autoCreateJmsQueues,
@Parameter(desc = "allow auto-created queues to be deleted automatically", name = "autoDeleteJmsQueues") boolean autoDeleteJmsQueues) throws Exception;
void removeAddressSettings(String addressMatch) throws Exception;

View File

@ -60,6 +60,10 @@ public final class AddressSettingsInfo
private final String slowConsumerPolicy;
private final boolean autoCreateJmsQueues;
private final boolean autoDeleteJmsQueues;
// Static --------------------------------------------------------
public static AddressSettingsInfo from(final String jsonString) throws Exception
@ -80,7 +84,9 @@ public final class AddressSettingsInfo
object.getBoolean("sendToDLAOnNoRoute"),
object.getLong("slowConsumerThreshold"),
object.getLong("slowConsumerCheckPeriod"),
object.getString("slowConsumerPolicy"));
object.getString("slowConsumerPolicy"),
object.getBoolean("autoCreateJmsQueues"),
object.getBoolean("autoDeleteJmsQueues"));
}
// Constructors --------------------------------------------------
@ -100,7 +106,9 @@ public final class AddressSettingsInfo
boolean sendToDLAOnNoRoute,
long slowConsumerThreshold,
long slowConsumerCheckPeriod,
String slowConsumerPolicy)
String slowConsumerPolicy,
boolean autoCreateJmsQueues,
boolean autoDeleteJmsQueues)
{
this.addressFullMessagePolicy = addressFullMessagePolicy;
this.maxSizeBytes = maxSizeBytes;
@ -118,6 +126,8 @@ public final class AddressSettingsInfo
this.slowConsumerThreshold = slowConsumerThreshold;
this.slowConsumerCheckPeriod = slowConsumerCheckPeriod;
this.slowConsumerPolicy = slowConsumerPolicy;
this.autoCreateJmsQueues = autoCreateJmsQueues;
this.autoDeleteJmsQueues = autoDeleteJmsQueues;
}
// Public --------------------------------------------------------
@ -206,5 +216,15 @@ public final class AddressSettingsInfo
{
return slowConsumerPolicy;
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues;
}
public boolean isAutoDeleteJmsQueues()
{
return autoDeleteJmsQueues;
}
}

View File

@ -24,15 +24,17 @@ import org.apache.activemq.api.core.client.ClientSession;
public class AddressQueryImpl implements ClientSession.AddressQuery, ClientSession.BindingQuery
{
private final boolean exists;
private final ArrayList<SimpleString> queueNames;
public AddressQueryImpl(final boolean exists, final List<SimpleString> queueNames)
private final boolean autoCreateJmsQueues;
public AddressQueryImpl(final boolean exists, final List<SimpleString> queueNames, final boolean autoCreateJmsQueues)
{
this.exists = exists;
this.queueNames = new ArrayList<SimpleString>(queueNames);
this.autoCreateJmsQueues = autoCreateJmsQueues;
}
public List<SimpleString> getQueueNames()
@ -44,4 +46,9 @@ public class AddressQueryImpl implements ClientSession.AddressQuery, ClientSessi
{
return exists;
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues;
}
}

View File

@ -38,6 +38,8 @@ public class QueueQueryImpl implements ClientSession.QueueQuery
private final SimpleString name;
private final boolean autoCreateJmsQueues;
public QueueQueryImpl(final boolean durable,
final boolean temporary,
final int consumerCount,
@ -47,7 +49,19 @@ public class QueueQueryImpl implements ClientSession.QueueQuery
final SimpleString name,
final boolean exists)
{
this(durable, temporary, consumerCount, messageCount, filterString, address, name, exists, false);
}
public QueueQueryImpl(final boolean durable,
final boolean temporary,
final int consumerCount,
final long messageCount,
final SimpleString filterString,
final SimpleString address,
final SimpleString name,
final boolean exists,
final boolean autoCreateJmsQueues)
{
this.durable = durable;
this.temporary = temporary;
this.consumerCount = consumerCount;
@ -56,6 +70,7 @@ public class QueueQueryImpl implements ClientSession.QueueQuery
this.address = address;
this.name = name;
this.exists = exists;
this.autoCreateJmsQueues = autoCreateJmsQueues;
}
public SimpleString getName()
@ -88,6 +103,11 @@ public class QueueQueryImpl implements ClientSession.QueueQuery
return durable;
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues;
}
public boolean isTemporary()
{
return temporary;

View File

@ -60,7 +60,7 @@ import org.apache.activemq.core.protocol.core.impl.wireformat.RollbackMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionAcknowledgeMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionAddMetaDataMessageV2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryResponseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryResponseMessage_V2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionCloseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionConsumerCloseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionConsumerFlowCreditMessage;
@ -72,7 +72,7 @@ import org.apache.activemq.core.protocol.core.impl.wireformat.SessionIndividualA
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionProducerCreditsFailMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionProducerCreditsMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryResponseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryResponseMessage_V2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionReceiveContinuationMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionReceiveLargeMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionReceiveMessage;
@ -231,13 +231,11 @@ public class ActiveMQSessionContext extends SessionContext
public ClientSession.QueueQuery queueQuery(final SimpleString queueName) throws ActiveMQException
{
SessionQueueQueryMessage request = new SessionQueueQueryMessage(queueName);
SessionQueueQueryResponseMessage response = (SessionQueueQueryResponseMessage) sessionChannel.sendBlocking(request, PacketImpl.SESS_QUEUEQUERY_RESP);
SessionQueueQueryResponseMessage_V2 response = (SessionQueueQueryResponseMessage_V2) sessionChannel.sendBlocking(request, PacketImpl.SESS_QUEUEQUERY_RESP_V2);
return response.toQueueQuery();
}
public ClientConsumerInternal createConsumer(SimpleString queueName, SimpleString filterString,
int windowSize, int maxRate, int ackBatchSize, boolean browseOnly,
Executor executor, Executor flowControlExecutor) throws ActiveMQException
@ -252,7 +250,7 @@ public class ActiveMQSessionContext extends SessionContext
browseOnly,
true);
SessionQueueQueryResponseMessage queueInfo = (SessionQueueQueryResponseMessage) sessionChannel.sendBlocking(request, PacketImpl.SESS_QUEUEQUERY_RESP);
SessionQueueQueryResponseMessage_V2 queueInfo = (SessionQueueQueryResponseMessage_V2) sessionChannel.sendBlocking(request, PacketImpl.SESS_QUEUEQUERY_RESP_V2);
// The actual windows size that gets used is determined by the user since
// could be overridden on the queue settings
@ -283,10 +281,10 @@ public class ActiveMQSessionContext extends SessionContext
public ClientSession.AddressQuery addressQuery(final SimpleString address) throws ActiveMQException
{
SessionBindingQueryResponseMessage response =
(SessionBindingQueryResponseMessage) sessionChannel.sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP);
SessionBindingQueryResponseMessage_V2 response =
(SessionBindingQueryResponseMessage_V2) sessionChannel.sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP_V2);
return new AddressQueryImpl(response.isExists(), response.getQueueNames());
return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateJmsQueues());
}

View File

@ -161,6 +161,10 @@ public final class ChannelImpl implements Channel
return version >= 125;
case PacketImpl.DISCONNECT_V2:
return version >= 125;
case PacketImpl.SESS_QUEUEQUERY_RESP_V2:
return version >= 126;
case PacketImpl.SESS_BINDINGQUERY_RESP_V2:
return version >= 126;
default:
return true;
}

View File

@ -39,6 +39,7 @@ import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_ADD_ME
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_ADD_METADATA2;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_BINDINGQUERY;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_BINDINGQUERY_RESP;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_BINDINGQUERY_RESP_V2;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_CLOSE;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_COMMIT;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_CONSUMER_CLOSE;
@ -52,6 +53,7 @@ import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_PRODUC
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_PRODUCER_REQUEST_CREDITS;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_QUEUEQUERY;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_QUEUEQUERY_RESP;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_QUEUEQUERY_RESP_V2;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_RECEIVE_CONTINUATION;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_ROLLBACK;
import static org.apache.activemq.core.protocol.core.impl.PacketImpl.SESS_SEND_CONTINUATION;
@ -107,6 +109,7 @@ import org.apache.activemq.core.protocol.core.impl.wireformat.SessionAddMetaData
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionAddMetaDataMessageV2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryResponseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryResponseMessage_V2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionCloseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionCommitMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionConsumerCloseMessage;
@ -120,6 +123,7 @@ import org.apache.activemq.core.protocol.core.impl.wireformat.SessionProducerCre
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionProducerCreditsMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryResponseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryResponseMessage_V2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionReceiveContinuationMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionRequestProducerCreditsMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionSendContinuationMessage;
@ -251,6 +255,11 @@ public abstract class PacketDecoder implements Serializable
packet = new SessionQueueQueryResponseMessage();
break;
}
case SESS_QUEUEQUERY_RESP_V2:
{
packet = new SessionQueueQueryResponseMessage_V2();
break;
}
case CREATE_QUEUE:
{
packet = new CreateQueueMessage();
@ -276,6 +285,11 @@ public abstract class PacketDecoder implements Serializable
packet = new SessionBindingQueryResponseMessage();
break;
}
case SESS_BINDINGQUERY_RESP_V2:
{
packet = new SessionBindingQueryResponseMessage_V2();
break;
}
case SESS_XA_START:
{
packet = new SessionXAStartMessage();

View File

@ -246,6 +246,10 @@ public class PacketImpl implements Packet
public static final byte SCALEDOWN_ANNOUNCEMENT = -6;
public static final byte SESS_QUEUEQUERY_RESP_V2 = -7;
public static final byte SESS_BINDINGQUERY_RESP_V2 = -8;
// Static --------------------------------------------------------
public PacketImpl(final byte type)

View File

@ -32,9 +32,9 @@ import org.apache.activemq.core.protocol.core.impl.PacketImpl;
*/
public class SessionBindingQueryResponseMessage extends PacketImpl
{
private boolean exists;
protected boolean exists;
private List<SimpleString> queueNames;
protected List<SimpleString> queueNames;
public SessionBindingQueryResponseMessage(final boolean exists, final List<SimpleString> queueNames)
{
@ -50,6 +50,11 @@ public class SessionBindingQueryResponseMessage extends PacketImpl
super(SESS_BINDINGQUERY_RESP);
}
public SessionBindingQueryResponseMessage(byte v2)
{
super(v2);
}
@Override
public boolean isResponse()
{

View File

@ -0,0 +1,90 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.core.protocol.core.impl.wireformat;
import java.util.List;
import org.apache.activemq.api.core.ActiveMQBuffer;
import org.apache.activemq.api.core.SimpleString;
/**
* @author Justin Bertram
*
*/
public class SessionBindingQueryResponseMessage_V2 extends SessionBindingQueryResponseMessage
{
private boolean autoCreateJmsQueues;
public SessionBindingQueryResponseMessage_V2(final boolean exists, final List<SimpleString> queueNames, final boolean autoCreateJmsQueues)
{
super(SESS_BINDINGQUERY_RESP_V2);
this.exists = exists;
this.queueNames = queueNames;
this.autoCreateJmsQueues = autoCreateJmsQueues;
}
public SessionBindingQueryResponseMessage_V2()
{
super(SESS_BINDINGQUERY_RESP_V2);
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues;
}
@Override
public void encodeRest(final ActiveMQBuffer buffer)
{
super.encodeRest(buffer);
buffer.writeBoolean(autoCreateJmsQueues);
}
@Override
public void decodeRest(final ActiveMQBuffer buffer)
{
super.decodeRest(buffer);
autoCreateJmsQueues = buffer.readBoolean();
}
@Override
public int hashCode()
{
final int prime = 31;
int result = super.hashCode();
result = prime * result + (autoCreateJmsQueues ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof SessionBindingQueryResponseMessage_V2))
return false;
SessionBindingQueryResponseMessage_V2 other = (SessionBindingQueryResponseMessage_V2)obj;
if (autoCreateJmsQueues != other.autoCreateJmsQueues)
return false;
return true;
}
}

View File

@ -32,21 +32,21 @@ import org.apache.activemq.core.server.QueueQueryResult;
*/
public class SessionQueueQueryResponseMessage extends PacketImpl
{
private SimpleString name;
protected SimpleString name;
private boolean exists;
protected boolean exists;
private boolean durable;
protected boolean durable;
private int consumerCount;
protected int consumerCount;
private long messageCount;
protected long messageCount;
private SimpleString filterString;
protected SimpleString filterString;
private SimpleString address;
protected SimpleString address;
private boolean temporary;
protected boolean temporary;
public SessionQueueQueryResponseMessage(final QueueQueryResult result)
{
@ -59,6 +59,11 @@ public class SessionQueueQueryResponseMessage extends PacketImpl
this(null, null, false, false, null, 0, 0, false);
}
public SessionQueueQueryResponseMessage(byte v2)
{
super(v2);
}
private SessionQueueQueryResponseMessage(final SimpleString name,
final SimpleString address,
final boolean durable,

View File

@ -0,0 +1,130 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.core.protocol.core.impl.wireformat;
import org.apache.activemq.api.core.ActiveMQBuffer;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.api.core.client.ClientSession;
import org.apache.activemq.core.client.impl.QueueQueryImpl;
import org.apache.activemq.core.server.QueueQueryResult;
/**
* @author Justin Bertram
*
*/
public class SessionQueueQueryResponseMessage_V2 extends SessionQueueQueryResponseMessage
{
private boolean autoCreationEnabled;
public SessionQueueQueryResponseMessage_V2(final QueueQueryResult result)
{
this(result.getName(), result.getAddress(), result.isDurable(), result.isTemporary(),
result.getFilterString(), result.getConsumerCount(), result.getMessageCount(), result.isExists(), result.isAutoCreateJmsQueues());
}
public SessionQueueQueryResponseMessage_V2()
{
this(null, null, false, false, null, 0, 0, false, false);
}
private SessionQueueQueryResponseMessage_V2(final SimpleString name,
final SimpleString address,
final boolean durable,
final boolean temporary,
final SimpleString filterString,
final int consumerCount,
final long messageCount,
final boolean exists,
final boolean autoCreationEnabled)
{
super(SESS_QUEUEQUERY_RESP_V2);
this.durable = durable;
this.temporary = temporary;
this.consumerCount = consumerCount;
this.messageCount = messageCount;
this.filterString = filterString;
this.address = address;
this.name = name;
this.exists = exists;
this.autoCreationEnabled = autoCreationEnabled;
}
public boolean isAutoCreationEnabled()
{
return autoCreationEnabled;
}
@Override
public void encodeRest(final ActiveMQBuffer buffer)
{
super.encodeRest(buffer);
buffer.writeBoolean(autoCreationEnabled);
}
@Override
public void decodeRest(final ActiveMQBuffer buffer)
{
super.decodeRest(buffer);
autoCreationEnabled = buffer.readBoolean();
}
@Override
public int hashCode()
{
final int prime = 31;
int result = super.hashCode();
result = prime * result + (autoCreationEnabled ? 1231 : 1237);
return result;
}
public ClientSession.QueueQuery toQueueQuery()
{
return new QueueQueryImpl(isDurable(),
isTemporary(),
getConsumerCount(),
getMessageCount(),
getFilterString(),
getAddress(),
getName(),
isExists(),
isAutoCreationEnabled());
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof SessionQueueQueryResponseMessage_V2))
return false;
SessionQueueQueryResponseMessage_V2 other = (SessionQueueQueryResponseMessage_V2)obj;
if (autoCreationEnabled != other.autoCreationEnabled)
return false;
return true;
}
}

View File

@ -43,29 +43,28 @@ public class QueueQueryResult
private boolean temporary;
private boolean autoCreateJmsQueues;
public QueueQueryResult(final SimpleString name,
final SimpleString address,
final boolean durable,
final boolean temporary,
final SimpleString filterString,
final int consumerCount,
final long messageCount)
final long messageCount,
final boolean autoCreateJmsQueues)
{
this(name, address, durable, temporary, filterString, consumerCount, messageCount, true);
this(name, address, durable, temporary, filterString, consumerCount, messageCount, autoCreateJmsQueues, true);
}
public QueueQueryResult()
{
this(null, null, false, false, null, 0, 0, false);
}
private QueueQueryResult(final SimpleString name,
public QueueQueryResult(final SimpleString name,
final SimpleString address,
final boolean durable,
final boolean temporary,
final SimpleString filterString,
final int consumerCount,
final long messageCount,
final boolean autoCreateJmsQueues,
final boolean exists)
{
this.durable = durable;
@ -82,6 +81,8 @@ public class QueueQueryResult
this.name = name;
this.autoCreateJmsQueues = autoCreateJmsQueues;
this.exists = exists;
}
@ -125,4 +126,9 @@ public class QueueQueryResult
return temporary;
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues;
}
}

View File

@ -28,7 +28,7 @@ import java.util.Iterator;
*
*
*/
public interface LinkedListIterator<E> extends Iterator<E>
public interface LinkedListIterator<E> extends Iterator<E>, AutoCloseable
{
void repeat();

View File

@ -21,4 +21,4 @@ activemq.version.microVersion=${activemq.version.microVersion}
activemq.version.incrementingVersion=${activemq.version.incrementingVersion}
activemq.version.versionSuffix=${activemq.version.versionSuffix}
activemq.version.versionTag=${activemq.version.versionTag}
activemq.version.compatibleVersionList=121,122,123,124,125
activemq.version.compatibleVersionList=121,122,123,124,125,126

View File

@ -414,9 +414,16 @@ public class ActiveMQMessageProducer implements MessageProducer, QueueSender, To
{
ClientSession.AddressQuery query = clientSession.addressQuery(address);
if (!query.isExists())
{
if (query.isAutoCreateJmsQueues())
{
clientSession.createQueue(address, address, true);
}
else
{
throw new InvalidDestinationException("Destination " + address + " does not exist");
}
}
else
{
connection.addKnownDestination(address);

View File

@ -325,9 +325,16 @@ public class ActiveMQSession implements QueueSession, TopicSession
ClientSession.AddressQuery response = session.addressQuery(jbd.getSimpleAddress());
if (!response.isExists())
{
if (response.isAutoCreateJmsQueues())
{
session.createQueue(jbd.getSimpleAddress(), jbd.getSimpleAddress(), true);
}
else
{
throw new InvalidDestinationException("Destination " + jbd.getName() + " does not exist");
}
}
connection.addKnownDestination(jbd.getSimpleAddress());
}
@ -730,7 +737,14 @@ public class ActiveMQSession implements QueueSession, TopicSession
if (!response.isExists())
{
throw new InvalidDestinationException("Queue " + dest.getName() + " does not exist");
if (response.isAutoCreateJmsQueues())
{
session.createQueue(dest.getSimpleAddress(), dest.getSimpleAddress(), true);
}
else
{
throw new InvalidDestinationException("Destination " + dest.getName() + " does not exist");
}
}
connection.addKnownDestination(dest.getSimpleAddress());
@ -902,10 +916,17 @@ public class ActiveMQSession implements QueueSession, TopicSession
try
{
AddressQuery message = session.addressQuery(new SimpleString(jbq.getAddress()));
if (!message.isExists())
AddressQuery response = session.addressQuery(new SimpleString(jbq.getAddress()));
if (!response.isExists())
{
throw new InvalidDestinationException(jbq.getAddress() + " does not exist");
if (response.isAutoCreateJmsQueues())
{
session.createQueue(jbq.getSimpleAddress(), jbq.getSimpleAddress(), true);
}
else
{
throw new InvalidDestinationException("Destination " + jbq.getName() + " does not exist");
}
}
}
catch (ActiveMQException e)
@ -1239,13 +1260,13 @@ public class ActiveMQSession implements QueueSession, TopicSession
QueueQuery response = session.queueQuery(queue.getSimpleAddress());
if (response.isExists())
if (!response.isExists() && !response.isAutoCreateJmsQueues())
{
return queue;
return null;
}
else
{
return null;
return queue;
}
}

View File

@ -135,7 +135,7 @@ public class ActiveMQBootstrap
{
restartFile.delete();
}
final Timer timer = new Timer("ActiveMQ Server Shutdown Timer", true);
final Timer timer = new Timer("ActiveMQ Server Shutdown Timer", false);
timer.scheduleAtFixedRate(new ServerStopTimerTask(stopFile, killFile, restartFile, timer), 500, 500);
}
}

View File

@ -152,6 +152,10 @@ public final class FileConfigurationParser extends XMLConfigurationUtil
private static final String SLOW_CONSUMER_POLICY_NODE_NAME = "slow-consumer-policy";
private static final String AUTO_CREATE_JMS_QUEUES = "auto-create-jms-queues";
private static final String AUTO_DELETE_JMS_QUEUES = "auto-delete-jms-queues";
// Attributes ----------------------------------------------------
private boolean validateAIO = false;
@ -1139,6 +1143,14 @@ public final class FileConfigurationParser extends XMLConfigurationUtil
SlowConsumerPolicy policy = Enum.valueOf(SlowConsumerPolicy.class, value);
addressSettings.setSlowConsumerPolicy(policy);
}
else if (AUTO_CREATE_JMS_QUEUES.equalsIgnoreCase(name))
{
addressSettings.setAutoCreateJmsQueues(XMLUtil.parseBoolean(child));
}
else if (AUTO_DELETE_JMS_QUEUES.equalsIgnoreCase(name))
{
addressSettings.setAutoDeleteJmsQueues(XMLUtil.parseBoolean(child));
}
}
return setting;
}

View File

@ -1635,6 +1635,8 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
policy = addressSettings.getSlowConsumerPolicy() == SlowConsumerPolicy.NOTIFY ? "NOTIFY"
: "KILL";
settings.put("slowConsumerPolicy", policy);
settings.put("autoCreateJmsQueues", addressSettings.isAutoCreateJmsQueues());
settings.put("autoDeleteJmsQueues", addressSettings.isAutoDeleteJmsQueues());
JSONObject jsonObject = new JSONObject(settings);
return jsonObject.toString();
@ -1658,7 +1660,9 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
final String addressFullMessagePolicy,
final long slowConsumerThreshold,
final long slowConsumerCheckPeriod,
final String slowConsumerPolicy) throws Exception
final String slowConsumerPolicy,
final boolean autoCreateJmsQueues,
final boolean autoDeleteJmsQueues) throws Exception
{
checkStarted();
@ -1721,6 +1725,8 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
{
addressSettings.setSlowConsumerPolicy(SlowConsumerPolicy.KILL);
}
addressSettings.setAutoCreateJmsQueues(autoCreateJmsQueues);
addressSettings.setAutoDeleteJmsQueues(autoDeleteJmsQueues);
server.getAddressSettingsRepository().addMatch(address, addressSettings);
storageManager.storeAddressSetting(new PersistedAddressSetting(new SimpleString(address), addressSettings));

View File

@ -1247,6 +1247,8 @@ final class PageSubscriptionImpl implements PageSubscription
private volatile boolean isredelivery = false;
private PagedReference currentDelivery = null;
private volatile PagedReference lastRedelivery = null;
// We only store the position for redeliveries. They will be read from the SoftCache again during delivery.
@ -1298,9 +1300,9 @@ final class PageSubscriptionImpl implements PageSubscription
if (cachedNext != null)
{
PagedReference retPos = cachedNext;
currentDelivery = cachedNext;
cachedNext = null;
return retPos;
return currentDelivery;
}
try
@ -1310,7 +1312,8 @@ final class PageSubscriptionImpl implements PageSubscription
position = getStartPosition();
}
return moveNext();
currentDelivery = moveNext();
return currentDelivery;
}
catch (RuntimeException e)
{
@ -1473,10 +1476,13 @@ final class PageSubscriptionImpl implements PageSubscription
public void remove()
{
deliveredCount.incrementAndGet();
PageCursorInfo info = PageSubscriptionImpl.this.getPageInfo(position);
if (currentDelivery != null)
{
PageCursorInfo info = PageSubscriptionImpl.this.getPageInfo(currentDelivery.getPosition());
if (info != null)
{
info.remove(position);
info.remove(currentDelivery.getPosition());
}
}
}

View File

@ -43,4 +43,6 @@ public interface QueueBindingInfo
SimpleString getFilterString();
boolean isAutoCreated();
}

View File

@ -2014,7 +2014,8 @@ public class JournalStorageManager implements StorageManager
PersistentQueueBindingEncoding bindingEncoding = new PersistentQueueBindingEncoding(queue.getName(),
binding.getAddress(),
filterString);
filterString,
queue.isAutoCreated());
readLock();
try
@ -3027,6 +3028,8 @@ public class JournalStorageManager implements StorageManager
public SimpleString filterString;
public boolean autoCreated;
public PersistentQueueBindingEncoding()
{
}
@ -3041,16 +3044,20 @@ public class JournalStorageManager implements StorageManager
address +
", filterString=" +
filterString +
", autoCreated=" +
autoCreated +
"]";
}
public PersistentQueueBindingEncoding(final SimpleString name,
final SimpleString address,
final SimpleString filterString)
final SimpleString filterString,
final boolean autoCreated)
{
this.name = name;
this.address = address;
this.filterString = filterString;
this.autoCreated = autoCreated;
}
public long getId()
@ -3083,11 +3090,17 @@ public class JournalStorageManager implements StorageManager
return name;
}
public boolean isAutoCreated()
{
return autoCreated;
}
public void decode(final ActiveMQBuffer buffer)
{
name = buffer.readSimpleString();
address = buffer.readSimpleString();
filterString = buffer.readNullableSimpleString();
autoCreated = buffer.readBoolean();
}
public void encode(final ActiveMQBuffer buffer)
@ -3095,12 +3108,13 @@ public class JournalStorageManager implements StorageManager
buffer.writeSimpleString(name);
buffer.writeSimpleString(address);
buffer.writeNullableSimpleString(filterString);
buffer.writeBoolean(autoCreated);
}
public int getEncodeSize()
{
return SimpleString.sizeofString(name) + SimpleString.sizeofString(address) +
SimpleString.sizeofNullableString(filterString);
SimpleString.sizeofNullableString(filterString) + DataConstants.SIZE_BOOLEAN;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.activemq.core.postoffice;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.core.transaction.Transaction;
@ -50,4 +51,6 @@ public interface AddressManager
Binding getBinding(SimpleString queueName);
Map<SimpleString, Binding> getBindings();
Set<SimpleString> getAddresses();
}

View File

@ -17,6 +17,7 @@
package org.apache.activemq.core.postoffice;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.api.core.Pair;
import org.apache.activemq.api.core.SimpleString;
@ -95,4 +96,6 @@ public interface PostOffice extends ActiveMQComponent
boolean isAddressBound(final SimpleString address) throws Exception;
Set<SimpleString> getAddresses();
}

View File

@ -861,6 +861,11 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
return notificationLock;
}
public Set<SimpleString> getAddresses()
{
return addressManager.getAddresses();
}
public void sendQueueInfoToQueue(final SimpleString queueName, final SimpleString address) throws Exception
{
// We send direct to the queue so we can send it to the same queue that is bound to the notifications address -

View File

@ -16,7 +16,9 @@
*/
package org.apache.activemq.core.postoffice.impl;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -151,6 +153,15 @@ public class SimpleAddressManager implements AddressManager
mappings.clear();
}
@Override
public Set<SimpleString> getAddresses()
{
Set<SimpleString> addresses = new HashSet<>();
addresses.addAll(mappings.keySet());
return addresses;
}
protected void removeBindingInternal(final SimpleString address, final SimpleString bindableName)
{
Bindings bindings = mappings.get(address);

View File

@ -72,6 +72,7 @@ import org.apache.activemq.core.protocol.core.impl.wireformat.SessionAddMetaData
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionAddMetaDataMessageV2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryResponseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionBindingQueryResponseMessage_V2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionConsumerCloseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionConsumerFlowCreditMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionCreateConsumerMessage;
@ -81,6 +82,7 @@ import org.apache.activemq.core.protocol.core.impl.wireformat.SessionForceConsum
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionIndividualAcknowledgeMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryResponseMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionQueueQueryResponseMessage_V2;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionRequestProducerCreditsMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionSendContinuationMessage;
import org.apache.activemq.core.protocol.core.impl.wireformat.SessionSendLargeMessage;
@ -230,7 +232,15 @@ public class ServerSessionPacketHandler implements ChannelHandler
{
// We send back queue information on the queue as a response- this allows the queue to
// be automatically recreated on failover
response = new SessionQueueQueryResponseMessage(session.executeQueueQuery(request.getQueueName()));
QueueQueryResult queueQueryResult = session.executeQueueQuery(request.getQueueName());
if (channel.supports(PacketImpl.SESS_QUEUEQUERY_RESP_V2))
{
response = new SessionQueueQueryResponseMessage_V2(queueQueryResult);
}
else
{
response = new SessionQueueQueryResponseMessage(queueQueryResult);
}
}
break;
@ -277,7 +287,14 @@ public class ServerSessionPacketHandler implements ChannelHandler
requiresResponse = true;
SessionQueueQueryMessage request = (SessionQueueQueryMessage)packet;
QueueQueryResult result = session.executeQueueQuery(request.getQueueName());
if (channel.supports(PacketImpl.SESS_QUEUEQUERY_RESP_V2))
{
response = new SessionQueueQueryResponseMessage_V2(result);
}
else
{
response = new SessionQueueQueryResponseMessage(result);
}
break;
}
case SESS_BINDINGQUERY:
@ -285,7 +302,14 @@ public class ServerSessionPacketHandler implements ChannelHandler
requiresResponse = true;
SessionBindingQueryMessage request = (SessionBindingQueryMessage)packet;
BindingQueryResult result = session.executeBindingQuery(request.getAddress());
if (channel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V2))
{
response = new SessionBindingQueryResponseMessage_V2(result.isExists(), result.getQueueNames(), result.isAutoCreateJmsQueues());
}
else
{
response = new SessionBindingQueryResponseMessage(result.isExists(), result.getQueueNames());
}
break;
}
case SESS_ACKNOWLEDGE:

View File

@ -177,6 +177,13 @@ public interface ActiveMQServer extends ActiveMQComponent
boolean durable,
boolean temporary) throws Exception;
Queue createQueue(SimpleString address,
SimpleString queueName,
SimpleString filter,
boolean durable,
boolean temporary,
boolean autoCreated) throws Exception;
Queue deployQueue(SimpleString address,
SimpleString queueName,
SimpleString filterString,

View File

@ -1366,4 +1366,8 @@ public interface ActiveMQServerLogger extends BasicLogger
@Message(id = 224064, value = "Setting <{0}> is invalid with this HA Policy Configuration. Please use <ha-policy> exclusively or remove. Ignoring <{0}> value.", format = Message.Format.MESSAGE_FORMAT)
void incompatibleWithHAPolicyChosen(String parameter);
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 224065, value = "Failed to remove auto-created queue {0}", format = Message.Format.MESSAGE_FORMAT)
void errorRemovingAutoCreatedQueue(@Cause Exception e, SimpleString bindingName);
}

View File

@ -0,0 +1,29 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.core.server;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.utils.ReferenceCounter;
/**
* @author Clebert Suconic
*/
public interface AutoCreatedQueueManager extends ReferenceCounter
{
SimpleString getQueueName();
}

View File

@ -33,11 +33,15 @@ public class BindingQueryResult
private List<SimpleString> queueNames;
public BindingQueryResult(final boolean exists, final List<SimpleString> queueNames)
private boolean autoCreateJmsQueues;
public BindingQueryResult(final boolean exists, final List<SimpleString> queueNames, final boolean autoCreateJmsQueues)
{
this.exists = exists;
this.queueNames = queueNames;
this.autoCreateJmsQueues = autoCreateJmsQueues;
}
public boolean isExists()
@ -45,6 +49,11 @@ public class BindingQueryResult
return exists;
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues;
}
public List<SimpleString> getQueueNames()
{
return queueNames;

View File

@ -49,6 +49,8 @@ public interface Queue extends Bindable
boolean isTemporary();
boolean isAutoCreated();
void addConsumer(Consumer consumer) throws Exception;
void removeConsumer(Consumer consumer);
@ -62,7 +64,7 @@ public interface Queue extends Bindable
* on shared subscriptions where the queue needs to be deleted when all the
* consumers are closed.
*/
void setConsumersRefCount(ActiveMQServer server);
void setConsumersRefCount(ReferenceCounter referenceCounter);
ReferenceCounter getConsumersRefCount();
@ -176,6 +178,10 @@ public interface Queue extends Bindable
boolean checkRedelivery(MessageReference ref, long timeBase, boolean ignoreRedeliveryDelay) throws Exception;
/**
* It will iterate thorugh memory only (not paging)
* @return
*/
LinkedListIterator<MessageReference> iterator();
LinkedListIterator<MessageReference> totalIterator();
@ -228,7 +234,10 @@ public interface Queue extends Bindable
void incrementMesssagesAdded();
List<MessageReference> cancelScheduledMessages();
/**
* cancels scheduled messages and send them to the head of the queue.
*/
void deliverScheduledMessages();
void postAcknowledge(MessageReference ref);

View File

@ -39,7 +39,8 @@ public interface QueueFactory
Filter filter,
PageSubscription pageSubscription,
boolean durable,
boolean temporary);
boolean temporary,
boolean autoCreated);
/**
* This is required for delete-all-reference to work correctly with paging

View File

@ -1193,9 +1193,18 @@ public class ActiveMQServerImpl implements ActiveMQServer
final boolean durable,
final boolean temporary) throws Exception
{
return createQueue(address, queueName, filterString, durable, temporary, false, false);
return createQueue(address, queueName, filterString, durable, temporary, false, false, false);
}
public Queue createQueue(final SimpleString address,
final SimpleString queueName,
final SimpleString filterString,
final boolean durable,
final boolean temporary,
final boolean autoCreated) throws Exception
{
return createQueue(address, queueName, filterString, durable, temporary, false, false, autoCreated);
}
/**
* Creates a transient queue. A queue that will exist as long as there are consumers.
@ -1214,7 +1223,7 @@ public class ActiveMQServerImpl implements ActiveMQServer
final SimpleString filterString,
boolean durable) throws Exception
{
Queue queue = createQueue(address, name, filterString, durable, !durable, true, !durable);
Queue queue = createQueue(address, name, filterString, durable, !durable, true, !durable, false);
if (!queue.getAddress().equals(address))
{
@ -1263,7 +1272,7 @@ public class ActiveMQServerImpl implements ActiveMQServer
{
ActiveMQServerLogger.LOGGER.deployQueue(queueName);
return createQueue(address, queueName, filterString, durable, temporary, true, false);
return createQueue(address, queueName, filterString, durable, temporary, true, false, false);
}
public void destroyQueue(final SimpleString queueName) throws Exception
@ -1981,7 +1990,8 @@ public class ActiveMQServerImpl implements ActiveMQServer
final boolean durable,
final boolean temporary,
final boolean ignoreIfExists,
final boolean transientQueue) throws Exception
final boolean transientQueue,
final boolean autoCreated) throws Exception
{
QueueBinding binding = (QueueBinding) postOffice.getBinding(queueName);
@ -2021,11 +2031,16 @@ public class ActiveMQServerImpl implements ActiveMQServer
filter,
pageSubscription,
durable,
temporary);
temporary,
autoCreated);
if (transientQueue)
{
queue.setConsumersRefCount(this);
queue.setConsumersRefCount(new TransientQueueManagerImpl(this, queueName));
}
else if (autoCreated)
{
queue.setConsumersRefCount(new AutoCreatedQueueManagerImpl(this, queueName));
}
binding = new LocalQueueBinding(address, queue, nodeManager.getNodeId());

View File

@ -0,0 +1,93 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.core.server.impl;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.core.server.ActiveMQServer;
import org.apache.activemq.core.server.ActiveMQServerLogger;
import org.apache.activemq.core.server.AutoCreatedQueueManager;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.utils.ReferenceCounterUtil;
/**
* @author Clebert Suconic
*/
public class AutoCreatedQueueManagerImpl implements AutoCreatedQueueManager
{
private final SimpleString queueName;
private final ActiveMQServer server;
private final Runnable runnable = new Runnable()
{
public void run()
{
try
{
Queue queue = server.locateQueue(queueName);
long consumerCount = queue.getConsumerCount();
long messageCount = queue.getMessageCount();
if (server.locateQueue(queueName).getMessageCount() == 0)
{
if (ActiveMQServerLogger.LOGGER.isDebugEnabled())
{
ActiveMQServerLogger.LOGGER.debug("deleting auto-created queue \"" + queueName + "\" because consumerCount = " + consumerCount + " and messageCount = " + messageCount);
}
server.destroyQueue(queueName, null, false);
}
else if (ActiveMQServerLogger.LOGGER.isDebugEnabled())
{
ActiveMQServerLogger.LOGGER.debug("NOT deleting auto-created queue \"" + queueName + "\" because consumerCount = " + consumerCount + " and messageCount = " + messageCount);
}
}
catch (Exception e)
{
ActiveMQServerLogger.LOGGER.errorRemovingAutoCreatedQueue(e, queueName);
}
}
};
private final ReferenceCounterUtil referenceCounterUtil = new ReferenceCounterUtil(runnable);
public AutoCreatedQueueManagerImpl(ActiveMQServer server, SimpleString queueName)
{
this.server = server;
this.queueName = queueName;
}
@Override
public int increment()
{
return referenceCounterUtil.increment();
}
@Override
public int decrement()
{
return referenceCounterUtil.decrement();
}
@Override
public SimpleString getQueueName()
{
return queueName;
}
}

View File

@ -90,7 +90,7 @@ public class BackupRecoveryJournalLoader extends PostOfficeJournalLoader
@Override
public void postLoad(Journal messageJournal, ResourceManager resourceManager, Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap) throws Exception
{
ScaleDownHandler scaleDownHandler = new ScaleDownHandler(pagingManager, postOffice, nodeManager, clusterController);
ScaleDownHandler scaleDownHandler = new ScaleDownHandler(pagingManager, postOffice, nodeManager, clusterController, parentServer.getStorageManager());
locator.setProtocolManagerFactory(ActiveMQServerSideProtocolManagerFactory.getInstance());
try (ClientSessionFactory sessionFactory = locator.createSessionFactory())

View File

@ -55,6 +55,7 @@ public class LastValueQueue extends QueueImpl
final PageSubscription pageSubscription,
final boolean durable,
final boolean temporary,
final boolean autoCreated,
final ScheduledExecutorService scheduledExecutor,
final PostOffice postOffice,
final StorageManager storageManager,
@ -68,6 +69,7 @@ public class LastValueQueue extends QueueImpl
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,

View File

@ -187,7 +187,8 @@ public class LiveOnlyActivation extends Activation
ScaleDownHandler scaleDownHandler = new ScaleDownHandler(activeMQServer.getPagingManager(),
activeMQServer.getPostOffice(),
activeMQServer.getNodeManager(),
activeMQServer.getClusterManager().getClusterController());
activeMQServer.getClusterManager().getClusterController(),
activeMQServer.getStorageManager());
ConcurrentMap<SimpleString, DuplicateIDCache> duplicateIDCaches = ((PostOfficeImpl) activeMQServer.getPostOffice()).getDuplicateIDCaches();
Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap = new HashMap<>();
for (SimpleString address : duplicateIDCaches.keySet())

View File

@ -46,6 +46,7 @@ import org.apache.activemq.core.postoffice.Binding;
import org.apache.activemq.core.postoffice.DuplicateIDCache;
import org.apache.activemq.core.postoffice.PostOffice;
import org.apache.activemq.core.postoffice.impl.LocalQueueBinding;
import org.apache.activemq.core.postoffice.impl.PostOfficeImpl;
import org.apache.activemq.core.server.ActiveMQServerLogger;
import org.apache.activemq.core.server.MessageReference;
import org.apache.activemq.core.server.NodeManager;
@ -155,7 +156,13 @@ public class PostOfficeJournalLoader implements JournalLoader
filter,
subscription,
true,
false);
false,
queueBindingInfo.isAutoCreated());
if (queueBindingInfo.isAutoCreated())
{
queue.setConsumersRefCount(new AutoCreatedQueueManagerImpl(((PostOfficeImpl)postOffice).getServer(), queueBindingInfo.getQueueName()));
}
Binding binding = new LocalQueueBinding(queueBindingInfo.getAddress(), queue, nodeManager.getNodeId());

View File

@ -75,7 +75,8 @@ public class QueueFactoryImpl implements QueueFactory
final Filter filter,
final PageSubscription pageSubscription,
final boolean durable,
final boolean temporary)
final boolean temporary,
final boolean autoCreated)
{
AddressSettings addressSettings = addressSettingsRepository.getMatch(address.toString());
@ -89,6 +90,7 @@ public class QueueFactoryImpl implements QueueFactory
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,
@ -104,6 +106,7 @@ public class QueueFactoryImpl implements QueueFactory
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,

View File

@ -61,7 +61,6 @@ import org.apache.activemq.core.server.ActiveMQServerLogger;
import org.apache.activemq.core.server.Consumer;
import org.apache.activemq.core.server.HandleStatus;
import org.apache.activemq.core.server.ActiveMQMessageBundle;
import org.apache.activemq.core.server.ActiveMQServer;
import org.apache.activemq.core.server.MessageReference;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.core.server.RoutingContext;
@ -131,6 +130,8 @@ public class QueueImpl implements Queue
private final boolean temporary;
private final boolean autoCreated;
private final PostOffice postOffice;
private volatile boolean queueDestroyed = false;
@ -315,6 +316,7 @@ public class QueueImpl implements Queue
final Filter filter,
final boolean durable,
final boolean temporary,
final boolean autoCreated,
final ScheduledExecutorService scheduledExecutor,
final PostOffice postOffice,
final StorageManager storageManager,
@ -328,6 +330,7 @@ public class QueueImpl implements Queue
null,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,
@ -342,6 +345,7 @@ public class QueueImpl implements Queue
final PageSubscription pageSubscription,
final boolean durable,
final boolean temporary,
final boolean autoCreated,
final ScheduledExecutorService scheduledExecutor,
final PostOffice postOffice,
final StorageManager storageManager,
@ -362,6 +366,8 @@ public class QueueImpl implements Queue
this.temporary = temporary;
this.autoCreated = autoCreated;
this.postOffice = postOffice;
this.storageManager = storageManager;
@ -425,11 +431,11 @@ public class QueueImpl implements Queue
}
// Queue implementation ----------------------------------------------------------------------------------------
public synchronized void setConsumersRefCount(final ActiveMQServer server)
public synchronized void setConsumersRefCount(final ReferenceCounter referenceCounter)
{
if (refCountForConsumers == null)
{
this.refCountForConsumers = new TransientQueueManagerImpl(server, this.name);
this.refCountForConsumers = referenceCounter;
}
}
@ -449,6 +455,11 @@ public class QueueImpl implements Queue
return temporary;
}
public boolean isAutoCreated()
{
return autoCreated;
}
public SimpleString getName()
{
return name;
@ -1220,9 +1231,18 @@ public class QueueImpl implements Queue
}
@Override
public List<MessageReference> cancelScheduledMessages()
public void deliverScheduledMessages()
{
return scheduledDeliveryHandler.cancel(null);
List<MessageReference> scheduledMessages = scheduledDeliveryHandler.cancel(null);
if (scheduledMessages != null && scheduledMessages.size() > 0)
{
for (MessageReference ref : scheduledMessages)
{
ref.getMessage().putLongProperty(MessageImpl.HDR_SCHEDULED_DELIVERY_TIME, ref.getScheduledDeliveryTime());
ref.setScheduledDeliveryTime(0);
}
this.addHead(scheduledMessages);
}
}
public long getMessagesAdded()
@ -3105,6 +3125,8 @@ public class QueueImpl implements Queue
Iterator<MessageReference> interIterator = null;
LinkedListIterator<MessageReference> messagesIterator = null;
Iterator lastIterator = null;
public TotalQueueIterator()
{
if (pageSubscription != null)
@ -3118,18 +3140,21 @@ public class QueueImpl implements Queue
@Override
public boolean hasNext()
{
if (messagesIterator.hasNext())
if (messagesIterator != null && messagesIterator.hasNext())
{
lastIterator = messagesIterator;
return true;
}
if (interIterator.hasNext())
{
lastIterator = interIterator;
return true;
}
if (pageIter != null)
{
if (pageIter.hasNext())
{
lastIterator = pageIter;
return true;
}
}
@ -3140,18 +3165,21 @@ public class QueueImpl implements Queue
@Override
public MessageReference next()
{
if (messagesIterator.hasNext())
if (messagesIterator != null && messagesIterator.hasNext())
{
return messagesIterator.next();
MessageReference msg = messagesIterator.next();
return msg;
}
if (interIterator.hasNext())
{
lastIterator = interIterator;
return interIterator.next();
}
if (pageIter != null)
{
if (pageIter.hasNext())
{
lastIterator = pageIter;
return pageIter.next();
}
}
@ -3162,6 +3190,10 @@ public class QueueImpl implements Queue
@Override
public void remove()
{
if (lastIterator != null)
{
lastIterator.remove();
}
}
@Override
@ -3172,10 +3204,16 @@ public class QueueImpl implements Queue
@Override
public void close()
{
if (pageIter != null) pageIter.close();
if (pageIter != null)
{
pageIter.close();
}
if (messagesIterator != null)
{
messagesIterator.close();
}
}
}
private int incDelivering()
{

View File

@ -20,11 +20,13 @@ import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.activemq.api.core.Message;
import org.apache.activemq.api.core.Pair;
@ -42,7 +44,9 @@ import org.apache.activemq.core.paging.PagingManager;
import org.apache.activemq.core.paging.PagingStore;
import org.apache.activemq.core.paging.cursor.PageSubscription;
import org.apache.activemq.core.paging.cursor.PagedReference;
import org.apache.activemq.core.persistence.StorageManager;
import org.apache.activemq.core.postoffice.Binding;
import org.apache.activemq.core.postoffice.Bindings;
import org.apache.activemq.core.postoffice.PostOffice;
import org.apache.activemq.core.postoffice.impl.LocalQueueBinding;
import org.apache.activemq.core.postoffice.impl.PostOfficeImpl;
@ -56,6 +60,7 @@ import org.apache.activemq.core.server.cluster.ClusterController;
import org.apache.activemq.core.transaction.ResourceManager;
import org.apache.activemq.core.transaction.Transaction;
import org.apache.activemq.core.transaction.TransactionOperation;
import org.apache.activemq.core.transaction.impl.TransactionImpl;
import org.apache.activemq.utils.LinkedListIterator;
public class ScaleDownHandler
@ -64,14 +69,16 @@ public class ScaleDownHandler
final PostOffice postOffice;
private NodeManager nodeManager;
private final ClusterController clusterController;
private final StorageManager storageManager;
private String targetNodeId;
public ScaleDownHandler(PagingManager pagingManager, PostOffice postOffice, NodeManager nodeManager, ClusterController clusterController)
public ScaleDownHandler(PagingManager pagingManager, PostOffice postOffice, NodeManager nodeManager, ClusterController clusterController, StorageManager storageManager)
{
this.pagingManager = pagingManager;
this.postOffice = postOffice;
this.nodeManager = nodeManager;
this.clusterController = clusterController;
this.storageManager = storageManager;
}
public long scaleDown(ClientSessionFactory sessionFactory,
@ -91,83 +98,189 @@ public class ScaleDownHandler
return num;
}
private long scaleDownMessages(ClientSessionFactory sessionFactory, SimpleString nodeId) throws Exception
public long scaleDownMessages(ClientSessionFactory sessionFactory, SimpleString nodeId) throws Exception
{
long messageCount = 0;
targetNodeId = nodeId != null ? nodeId.toString() : getTargetNodeId(sessionFactory);
ClientSession session = sessionFactory.createSession(false, true, true);
Map<String, Long> queueIDs = new HashMap<>();
try (ClientSession session = sessionFactory.createSession(false, true, true))
{
ClientProducer producer = session.createProducer();
List<SimpleString> addresses = new ArrayList<>();
for (Map.Entry<SimpleString, Binding> entry : postOffice.getAllBindings().entrySet())
// perform a loop per address
for (SimpleString address : postOffice.getAddresses())
{
if (entry.getValue() instanceof LocalQueueBinding)
{
SimpleString address = entry.getValue().getAddress();
ActiveMQServerLogger.LOGGER.debug("Scaling down address " + address);
Bindings bindings = postOffice.getBindingsForAddress(address);
// There is a special case involving store-and-forward queues used for clustering.
// If this queue is supposed to forward messages to the server that I'm scaling down to I need to handle these messages differently.
boolean storeAndForward = false;
if (address.toString().startsWith("sf."))
{
// these get special treatment later
storeAndForward = true;
}
// this means we haven't inspected this address before
if (!addresses.contains(address))
{
addresses.add(address);
PagingStore store = pagingManager.getPageStore(address);
// compile a list of all the relevant queues and queue iterators for this address
List<Queue> queues = new ArrayList<>();
Map<SimpleString, LinkedListIterator<MessageReference>> queueIterators = new HashMap<>();
for (Binding binding : postOffice.getBindingsForAddress(address).getBindings())
// It will get a list of queues on this address, ordered by the number of messages
Set<Queue> queues = new TreeSet<>(new OrderQueueByNumberOfReferencesComparator());
for (Binding binding : bindings.getBindings())
{
if (binding instanceof LocalQueueBinding)
{
Queue queue = ((LocalQueueBinding) binding).getQueue();
//remove the scheduled messages and reset on the actual message ready for sending
//we may set the time multiple times on a message but it will always be the same.
//set the ref scheduled time to 0 so it is in the queue ready for resending
List<MessageReference> messageReferences = queue.cancelScheduledMessages();
for (MessageReference ref : messageReferences)
{
ref.getMessage().putLongProperty(MessageImpl.HDR_SCHEDULED_DELIVERY_TIME, ref.getScheduledDeliveryTime());
ref.setScheduledDeliveryTime(0);
}
queue.addHead(messageReferences);
// as part of scale down we will cancel any scheduled message and pass it to theWhile we scan for the queues we will also cancel any scheduled messages and deliver them right away
queue.deliverScheduledMessages();
queues.add(queue);
queueIterators.put(queue.getName(), queue.totalIterator());
}
}
// sort into descending order - order is based on the number of references in the queue
Collections.sort(queues, new OrderQueueByNumberOfReferencesComparator());
// loop through every queue on this address
List<SimpleString> checkedQueues = new ArrayList<>();
for (Queue bigLoopQueue : queues)
if (address.toString().startsWith("sf."))
{
checkedQueues.add(bigLoopQueue.getName());
messageCount += scaleDownSNF(address, queues, producer);
}
else
{
messageCount += scaleDownRegularMessages(address, queues, session, producer);
}
}
}
return messageCount;
}
public long scaleDownRegularMessages(final SimpleString address, final Set<Queue> queues, final ClientSession clientSession, final ClientProducer producer) throws Exception
{
ActiveMQServerLogger.LOGGER.debug("Scaling down messages on address " + address);
long messageCount = 0;
final HashMap<Queue, QueuesXRefInnerManager> controls = new HashMap<Queue, QueuesXRefInnerManager>();
PagingStore pageStore = pagingManager.getPageStore(address);
Transaction tx = new TransactionImpl(storageManager);
pageStore.disableCleanup();
LinkedListIterator<MessageReference> bigLoopMessageIterator = bigLoopQueue.totalIterator();
try
{
// loop through every message of this queue
while (bigLoopMessageIterator.hasNext())
{
MessageReference bigLoopRef = bigLoopMessageIterator.next();
Message message = bigLoopRef.getMessage().copy();
if (storeAndForward)
for (Queue queue : queues)
{
if (address.toString().endsWith(targetNodeId))
controls.put(queue, new QueuesXRefInnerManager(clientSession, queue, pageStore));
}
// compile a list of all the relevant queues and queue iterators for this address
for (Queue loopQueue : queues)
{
ActiveMQServerLogger.LOGGER.debug("Scaling down messages on address " + address + " / performing loop on queue " + loopQueue);
try (LinkedListIterator<MessageReference> messagesIterator = loopQueue.totalIterator())
{
while (messagesIterator.hasNext())
{
MessageReference messageReference = messagesIterator.next();
Message message = messageReference.getMessage().copy();
ActiveMQServerLogger.LOGGER.debug("Reading message " + message + " from queue " + loopQueue);
Set<QueuesXRefInnerManager> queuesFound = new HashSet<>();
for (Map.Entry<Queue, QueuesXRefInnerManager> controlEntry : controls.entrySet())
{
if (controlEntry.getKey() == loopQueue)
{
// no need to lookup on itself, we just add it
queuesFound.add(controlEntry.getValue());
}
else if (controlEntry.getValue().lookup(messageReference))
{
ActiveMQServerLogger.LOGGER.debug("Message existed on queue " + controlEntry.getKey().getID() + " removeID=" + controlEntry.getValue().getQueueID());
queuesFound.add(controlEntry.getValue());
}
}
// get the ID for every queue that contains the message
ByteBuffer buffer = ByteBuffer.allocate(queuesFound.size() * 8);
for (QueuesXRefInnerManager control : queuesFound)
{
long queueID = control.getQueueID();
buffer.putLong(queueID);
}
message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
if (ActiveMQServerLogger.LOGGER.isDebugEnabled())
{
if (messageReference.isPaged())
{
ActiveMQServerLogger.LOGGER.debug("*********************<<<<< Scaling down pdgmessage " + message);
}
else
{
ActiveMQServerLogger.LOGGER.debug("*********************<<<<< Scaling down message " + message);
}
}
producer.send(address, message);
messageCount++;
messagesIterator.remove();
// We need to perform the ack / removal after sending, otherwise the message could been removed before the send is finished
for (QueuesXRefInnerManager queueFound : queuesFound)
{
ackMessageOnQueue(tx, queueFound.getQueue(), messageReference);
}
}
}
}
tx.commit();
for (QueuesXRefInnerManager controlRemoved : controls.values())
{
controlRemoved.close();
}
return messageCount;
}
finally
{
pageStore.enableCleanup();
pageStore.getCursorProvider().scheduleCleanup();
}
}
private long scaleDownSNF(final SimpleString address, final Set<Queue> queues, final ClientProducer producer) throws Exception
{
long messageCount = 0;
final String propertyEnd;
// If this SNF is towards our targetNodeId
boolean queueOnTarget = address.toString().endsWith(targetNodeId);
if (queueOnTarget)
{
propertyEnd = targetNodeId;
}
else
{
propertyEnd = address.toString().substring(address.toString().lastIndexOf("."));
}
Transaction tx = new TransactionImpl(storageManager);
for (Queue queue : queues)
{
// using auto-closeable
try (LinkedListIterator<MessageReference> messagesIterator = queue.totalIterator())
{
// loop through every message of this queue
while (messagesIterator.hasNext())
{
MessageReference messageRef = messagesIterator.next();
Message message = messageRef.getMessage().copy();
/* Here we are taking messages out of a store-and-forward queue and sending them to the corresponding
* address on the scale-down target server. However, we have to take the existing _HQ_ROUTE_TOsf.*
* property and put its value into the _HQ_ROUTE_TO property so the message is routed properly.
@ -181,7 +294,7 @@ public class ScaleDownHandler
{
if (propName.startsWith(MessageImpl.HDR_ROUTE_TO_IDS))
{
if (propName.toString().endsWith(targetNodeId))
if (propName.toString().endsWith(propertyEnd))
{
oldRouteToIDs = message.getBytesProperty(propName);
}
@ -189,120 +302,35 @@ public class ScaleDownHandler
}
}
// TODO: what if oldRouteToIDs == null ??
for (SimpleString propertyToRemove : propertiesToRemove)
{
message.removeProperty(propertyToRemove);
}
if (queueOnTarget)
{
message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, oldRouteToIDs);
}
else
{
/* Here we are taking messages out of a store-and-forward queue and sending them to the corresponding
* store-and-forward address on the scale-down target server. In this case we use a special property
* for the queue ID so that the scale-down target server can route it appropriately.
*/
byte[] oldRouteToIDs = null;
List<SimpleString> propertiesToRemove = new ArrayList<>();
message.removeProperty(MessageImpl.HDR_ROUTE_TO_IDS);
for (SimpleString propName : message.getPropertyNames())
{
if (propName.startsWith(MessageImpl.HDR_ROUTE_TO_IDS))
{
if (propName.toString().endsWith(address.toString().substring(address.toString().lastIndexOf("."))))
{
oldRouteToIDs = message.getBytesProperty(propName);
}
propertiesToRemove.add(propName);
}
}
for (SimpleString propertyToRemove : propertiesToRemove)
{
message.removeProperty(propertyToRemove);
}
message.putBytesProperty(MessageImpl.HDR_SCALEDOWN_TO_IDS, oldRouteToIDs);
}
ActiveMQServerLogger.LOGGER.debug("Scaling down message " + message + " from " + address + " to " + message.getAddress() + " on node " + targetNodeId);
producer.send(message.getAddress(), message);
messageCount++;
bigLoopQueue.deleteReference(message.getMessageID());
}
else
{
List<Queue> queuesWithMessage = new ArrayList<>();
queuesWithMessage.add(bigLoopQueue);
long messageId = message.getMessageID();
getQueuesWithMessage(store, queues, queueIterators, checkedQueues, bigLoopQueue, queuesWithMessage, bigLoopRef, messageId);
// get the ID for every queue that contains the message
ByteBuffer buffer = ByteBuffer.allocate(queuesWithMessage.size() * 8);
StringBuilder logMessage = new StringBuilder();
logMessage.append("Scaling down message ").append(messageId).append(" to ");
for (Queue queue : queuesWithMessage)
{
long queueID;
String queueName = queue.getName().toString();
if (queueIDs.containsKey(queueName))
{
queueID = queueIDs.get(queueName);
}
else
{
queueID = createQueueIfNecessaryAndGetID(session, queue, address);
queueIDs.put(queueName, queueID); // store it so we don't have to look it up every time
}
logMessage.append(queueName).append("(").append(queueID).append(")").append(", ");
buffer.putLong(queueID);
}
logMessage.delete(logMessage.length() - 2, logMessage.length()); // trim off the trailing comma and space
ActiveMQServerLogger.LOGGER.debug(logMessage.append(" on address ").append(address));
message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
//we need this incase we are sending back to the source server of the message, this basically
//acts like the bridge and ignores dup detection
if (message.containsProperty(MessageImpl.HDR_DUPLICATE_DETECTION_ID))
{
byte[] bytes = new byte[24];
ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.put(nodeManager.getUUID().asBytes());
bb.putLong(messageId);
message.putBytesProperty(MessageImpl.HDR_BRIDGE_DUPLICATE_ID, bb.array());
}
producer.send(address, message);
messageCount++;
// delete the reference from all queues which contain it
bigLoopQueue.deleteReference(messageId);
for (Queue queue : queuesWithMessage)
{
queue.deleteReference(messageId);
}
}
}
}
finally
{
bigLoopMessageIterator.close();
queueIterators.get(bigLoopQueue.getName()).close();
}
}
messagesIterator.remove();
ackMessageOnQueue(tx, queue, messageRef);
}
}
}
producer.close();
session.close();
tx.commit();
return messageCount;
}
@ -324,6 +352,8 @@ public class ScaleDownHandler
Transaction transaction = resourceManager.getTransaction(xid);
session.start(xid, XAResource.TMNOFLAGS);
List<TransactionOperation> allOperations = transaction.getAllOperations();
// Get the information of the Prepared TXs so it could replay the TXs
Map<ServerMessage, Pair<List<Long>, List<Long>>> queuesToSendTo = new HashMap<>();
for (TransactionOperation operation : allOperations)
{
@ -387,6 +417,7 @@ public class ScaleDownHandler
}
}
}
ClientProducer producer = session.createProducer();
for (Map.Entry<ServerMessage, Pair<List<Long>, List<Long>>> entry : queuesToSendTo.entrySet())
{
@ -436,78 +467,6 @@ public class ScaleDownHandler
}
session.close();
}
/**
* Loop through every *other* queue on this address to see if it also contains this message.
* Skip queues with filters that don't match as matching messages will never be in there.
* Also skip queues that we've already checked in the "big" loop.
*/
private void getQueuesWithMessage(PagingStore store, List<Queue> queues, Map<SimpleString, LinkedListIterator<MessageReference>> queueIterators, List<SimpleString> checkedQueues, Queue bigLoopQueue, List<Queue> queuesWithMessage, MessageReference bigLoopRef, long messageId) throws Exception
{
for (Queue queue : queues)
{
if (!checkedQueues.contains(queue.getName()) &&
((queue.getFilter() == null &&
bigLoopQueue.getFilter() == null) ||
(queue.getFilter() != null &&
queue.getFilter().equals(bigLoopQueue.getFilter()))))
{
// an optimization for paged messages, eliminates the need to (potentially) scan the whole queue
if (bigLoopRef.isPaged())
{
PageSubscription subscription = store.getCursorProvider().getSubscription(queue.getID());
if (subscription.contains((PagedReference) bigLoopRef))
{
queuesWithMessage.add(queue);
}
}
else
{
LinkedListIterator<MessageReference> queueIterator = queueIterators.get(queue.getName());
boolean first = true;
long initialMessageID = 0;
while (queueIterator.hasNext())
{
Message m = queueIterator.next().getMessage();
if (first)
{
initialMessageID = m.getMessageID();
first = false;
}
if (m.getMessageID() == messageId)
{
queuesWithMessage.add(queue);
break;
}
}
/**
* if we've reached the end then reset the iterator and go through again until we
* get back to the place where we started
*/
if (!queueIterator.hasNext())
{
queueIterator = queue.totalIterator();
queueIterators.put(queue.getName(), queueIterator);
while (queueIterator.hasNext())
{
Message m = queueIterator.next().getMessage();
if (m.getMessageID() == initialMessageID)
{
break;
}
else if (m.getMessageID() == messageId)
{
queuesWithMessage.add(queue);
break;
}
}
}
}
}
}
}
/**
* Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
* send directly to a queue, we have to send to an address instead but not all the queues related to the
@ -557,11 +516,159 @@ public class ScaleDownHandler
if (queue1 == queue2) return EQUAL;
if (queue1.getMessageCount() == queue2.getMessageCount()) return EQUAL;
if (queue1.getMessageCount() == queue2.getMessageCount())
{
// if it's the same count we will use the ID as a tie breaker:
long tieBreak = queue2.getID() - queue1.getID();
if (tieBreak > 0) return AFTER;
else if (tieBreak < 0) return BEFORE;
else return EQUAL; // EQUAL here shouldn't really happen... but lets do the check anyways
}
if (queue1.getMessageCount() > queue2.getMessageCount()) return BEFORE;
if (queue1.getMessageCount() < queue2.getMessageCount()) return AFTER;
return result;
}
}
private void ackMessageOnQueue(Transaction tx, Queue queue, MessageReference messageRef) throws Exception
{
queue.acknowledge(tx, messageRef);
}
/**
* this class will control iterations while
* looking over for messages relations
*/
private class QueuesXRefInnerManager
{
private final Queue queue;
private LinkedListIterator<MessageReference> memoryIterator;
private MessageReference lastRef = null;
private final PagingStore store;
/**
* ClientSession used for looking up and creating queues
*/
private final ClientSession clientSession;
private long targetQueueID = -1;
QueuesXRefInnerManager(final ClientSession clientSession, final Queue queue, final PagingStore store)
{
this.queue = queue;
this.store = store;
this.clientSession = clientSession;
}
public Queue getQueue()
{
return queue;
}
public long getQueueID() throws Exception
{
if (targetQueueID < 0)
{
targetQueueID = createQueueIfNecessaryAndGetID(clientSession, queue, queue.getAddress());
}
return targetQueueID;
}
public void close()
{
if (memoryIterator != null)
{
memoryIterator.close();
}
}
public boolean lookup(MessageReference reference) throws Exception
{
if (reference.isPaged())
{
PageSubscription subscription = store.getCursorProvider().getSubscription(queue.getID());
if (subscription.contains((PagedReference) reference))
{
return true;
}
}
else
{
if (lastRef != null && lastRef.getMessage().equals(reference.getMessage()))
{
lastRef = null;
memoryIterator.remove();
return true;
}
int numberOfScans = 2;
if (memoryIterator == null)
{
// If we have a brand new iterator, and we can't find something
numberOfScans = 1;
}
MessageReference initialRef = null;
for (int i = 0; i < numberOfScans; i++)
{
ActiveMQServerLogger.LOGGER.debug("iterating on queue " + queue + " while looking for reference " + reference);
memoryIterator = queue.iterator();
while (memoryIterator.hasNext())
{
lastRef = memoryIterator.next();
ActiveMQServerLogger.LOGGER.debug("Iterating on message " + lastRef);
if (lastRef.getMessage().equals(reference.getMessage()))
{
memoryIterator.remove();
lastRef = null;
return true;
}
if (initialRef == null)
{
lastRef = initialRef;
}
else
{
if (initialRef.equals(lastRef))
{
if (!memoryIterator.hasNext())
{
// if by coincidence we are at the end of the iterator, we just reset the iterator
lastRef = null;
memoryIterator.close();
memoryIterator = null;
}
return false;
}
}
}
}
}
// if we reached two iterations without finding anything.. we just go away by cleaning everything up
lastRef = null;
memoryIterator.close();
memoryIterator = null;
return false;
}
}
}

View File

@ -37,6 +37,7 @@ import org.apache.activemq.api.core.Pair;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.api.core.management.CoreNotificationType;
import org.apache.activemq.api.core.management.ManagementHelper;
import org.apache.activemq.api.core.management.ResourceNames;
import org.apache.activemq.core.client.impl.ClientMessageImpl;
import org.apache.activemq.core.exception.ActiveMQXAException;
import org.apache.activemq.core.filter.Filter;
@ -549,7 +550,15 @@ public class ServerSessionImpl implements ServerSession, FailureListener
securityStore.check(address, CheckType.CREATE_NON_DURABLE_QUEUE, this);
}
Queue queue = server.createQueue(address, name, filterString, durable, temporary);
// any non-temporary JMS queue created via this method should be marked as auto-created
if (!temporary && address.toString().startsWith(ResourceNames.JMS_QUEUE) && address.equals(name))
{
server.createQueue(address, name, filterString, durable, temporary, true);
}
else
{
server.createQueue(address, name, filterString, durable, temporary);
}
if (temporary)
{
@ -676,6 +685,8 @@ public class ServerSessionImpl implements ServerSession, FailureListener
public QueueQueryResult executeQueueQuery(final SimpleString name) throws Exception
{
boolean autoCreateJmsQueues = name.toString().startsWith(ResourceNames.JMS_QUEUE) && server.getAddressSettingsRepository().getMatch(name.toString()).isAutoCreateJmsQueues();
if (name == null)
{
throw ActiveMQMessageBundle.BUNDLE.queueNameIsNull();
@ -699,16 +710,21 @@ public class ServerSessionImpl implements ServerSession, FailureListener
queue.isTemporary(),
filterString,
queue.getConsumerCount(),
queue.getMessageCount());
queue.getMessageCount(),
autoCreateJmsQueues);
}
// make an exception for the management address (see HORNETQ-29)
else if (name.equals(managementAddress))
{
response = new QueueQueryResult(name, managementAddress, true, false, null, -1, -1);
response = new QueueQueryResult(name, managementAddress, true, false, null, -1, -1, autoCreateJmsQueues);
}
else if (autoCreateJmsQueues)
{
response = new QueueQueryResult(name, name, true, false, null, 0, 0, true, false);
}
else
{
response = new QueueQueryResult();
response = new QueueQueryResult(null, null, false, false, null, 0, 0, false, false);
}
return response;
@ -716,6 +732,8 @@ public class ServerSessionImpl implements ServerSession, FailureListener
public BindingQueryResult executeBindingQuery(final SimpleString address) throws Exception
{
boolean autoCreateJmsQueues = address.toString().startsWith(ResourceNames.JMS_QUEUE) && server.getAddressSettingsRepository().getMatch(address.toString()).isAutoCreateJmsQueues();
if (address == null)
{
throw ActiveMQMessageBundle.BUNDLE.addressIsNull();
@ -726,7 +744,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener
// make an exception for the management address (see HORNETQ-29)
if (address.equals(managementAddress))
{
return new BindingQueryResult(true, names);
return new BindingQueryResult(true, names, autoCreateJmsQueues);
}
Bindings bindings = postOffice.getMatchingBindings(address);
@ -739,7 +757,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener
}
}
return new BindingQueryResult(!names.isEmpty(), names);
return new BindingQueryResult(!names.isEmpty(), names, autoCreateJmsQueues);
}
public void forceConsumerDelivery(final long consumerID, final long sequence) throws Exception

View File

@ -56,6 +56,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
public static final boolean DEFAULT_LAST_VALUE_QUEUE = false;
public static final boolean DEFAULT_AUTO_CREATE_QUEUES = true;
public static final boolean DEFAULT_AUTO_DELETE_QUEUES = true;
public static final long DEFAULT_REDISTRIBUTION_DELAY = -1;
public static final long DEFAULT_EXPIRY_DELAY = -1;
@ -106,6 +110,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
private SlowConsumerPolicy slowConsumerPolicy = null;
private Boolean autoCreateJmsQueues = null;
private Boolean autoDeleteJmsQueues = null;
public AddressSettings(AddressSettings other)
{
this.addressFullMessagePolicy = other.addressFullMessagePolicy;
@ -127,6 +135,8 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
this.slowConsumerThreshold = other.slowConsumerThreshold;
this.slowConsumerCheckPeriod = other.slowConsumerCheckPeriod;
this.slowConsumerPolicy = other.slowConsumerPolicy;
this.autoCreateJmsQueues = other.autoCreateJmsQueues;
this.autoDeleteJmsQueues = other.autoDeleteJmsQueues;
}
public AddressSettings()
@ -134,6 +144,26 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
}
public boolean isAutoCreateJmsQueues()
{
return autoCreateJmsQueues != null ? autoCreateJmsQueues : AddressSettings.DEFAULT_AUTO_CREATE_QUEUES;
}
public void setAutoCreateJmsQueues(final boolean autoCreateJmsQueues)
{
this.autoCreateJmsQueues = autoCreateJmsQueues;
}
public boolean isAutoDeleteJmsQueues()
{
return autoDeleteJmsQueues != null ? autoDeleteJmsQueues : AddressSettings.DEFAULT_AUTO_DELETE_QUEUES;
}
public void setAutoDeleteJmsQueues(final boolean autoDeleteJmsQueues)
{
this.autoDeleteJmsQueues = autoDeleteJmsQueues;
}
public boolean isLastValueQueue()
{
return lastValueQueue != null ? lastValueQueue : AddressSettings.DEFAULT_LAST_VALUE_QUEUE;
@ -398,6 +428,14 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
{
slowConsumerPolicy = merged.slowConsumerPolicy;
}
if (autoCreateJmsQueues == null)
{
autoCreateJmsQueues = merged.autoCreateJmsQueues;
}
if (autoDeleteJmsQueues == null)
{
autoDeleteJmsQueues = merged.autoDeleteJmsQueues;
}
}
@Override
@ -458,6 +496,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
{
slowConsumerPolicy = null;
}
autoCreateJmsQueues = BufferHelper.readNullableBoolean(buffer);
autoDeleteJmsQueues = BufferHelper.readNullableBoolean(buffer);
}
@Override
@ -482,7 +524,9 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
BufferHelper.sizeOfNullableBoolean(sendToDLAOnNoRoute) +
BufferHelper.sizeOfNullableLong(slowConsumerCheckPeriod) +
BufferHelper.sizeOfNullableLong(slowConsumerThreshold) +
BufferHelper.sizeOfNullableSimpleString(slowConsumerPolicy != null ? slowConsumerPolicy.toString() : null);
BufferHelper.sizeOfNullableSimpleString(slowConsumerPolicy != null ? slowConsumerPolicy.toString() : null) +
BufferHelper.sizeOfNullableBoolean(autoCreateJmsQueues) +
BufferHelper.sizeOfNullableBoolean(autoDeleteJmsQueues);
}
@Override
@ -526,6 +570,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
BufferHelper.writeNullableLong(buffer, slowConsumerCheckPeriod);
buffer.writeNullableSimpleString(slowConsumerPolicy != null ? new SimpleString(slowConsumerPolicy.toString()) : null);
BufferHelper.writeNullableBoolean(buffer, autoCreateJmsQueues);
BufferHelper.writeNullableBoolean(buffer, autoDeleteJmsQueues);
}
/* (non-Javadoc)
@ -556,6 +604,8 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
result = prime * result + ((slowConsumerThreshold == null) ? 0 : slowConsumerThreshold.hashCode());
result = prime * result + ((slowConsumerCheckPeriod == null) ? 0 : slowConsumerCheckPeriod.hashCode());
result = prime * result + ((slowConsumerPolicy == null) ? 0 : slowConsumerPolicy.hashCode());
result = prime * result + ((autoCreateJmsQueues == null) ? 0 : autoCreateJmsQueues.hashCode());
result = prime * result + ((autoDeleteJmsQueues == null) ? 0 : autoDeleteJmsQueues.hashCode());
return result;
}
@ -705,6 +755,20 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
}
else if (!slowConsumerPolicy.equals(other.slowConsumerPolicy))
return false;
if (autoCreateJmsQueues == null)
{
if (other.autoCreateJmsQueues != null)
return false;
}
else if (!autoCreateJmsQueues.equals(other.autoCreateJmsQueues))
return false;
if (autoDeleteJmsQueues == null)
{
if (other.autoDeleteJmsQueues != null)
return false;
}
else if (!autoDeleteJmsQueues.equals(other.autoDeleteJmsQueues))
return false;
return true;
}
@ -751,6 +815,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
slowConsumerCheckPeriod +
", slowConsumerPolicy=" +
slowConsumerPolicy +
", autoCreateJmsQueues=" +
autoCreateJmsQueues +
", autoDeleteJmsQueues=" +
autoDeleteJmsQueues +
"]";
}
}

View File

@ -2258,6 +2258,23 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="auto-create-jms-queues" type="xsd:boolean" default="true" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
whether or not to automatically create JMS queues when a producer sends or a consumer connects to a
queue
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="auto-delete-jms-queues" type="xsd:boolean" default="true" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
whether or not to delete auto-created JMS queues when the queue has 0 consumers and 0 messages
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:all>
<xsd:attribute name="match" type="xsd:string" use="required">

View File

@ -297,6 +297,8 @@ public class FileConfigurationTest extends ConfigurationImplTest
assertEquals(10, conf.getAddressesSettings().get("a1").getSlowConsumerThreshold());
assertEquals(5, conf.getAddressesSettings().get("a1").getSlowConsumerCheckPeriod());
assertEquals(SlowConsumerPolicy.NOTIFY, conf.getAddressesSettings().get("a1").getSlowConsumerPolicy());
assertEquals(true, conf.getAddressesSettings().get("a1").isAutoCreateJmsQueues());
assertEquals(true, conf.getAddressesSettings().get("a1").isAutoDeleteJmsQueues());
assertEquals("a2.1", conf.getAddressesSettings().get("a2").getDeadLetterAddress().toString());
assertEquals("a2.2", conf.getAddressesSettings().get("a2").getExpiryAddress().toString());
@ -308,6 +310,8 @@ public class FileConfigurationTest extends ConfigurationImplTest
assertEquals(20, conf.getAddressesSettings().get("a2").getSlowConsumerThreshold());
assertEquals(15, conf.getAddressesSettings().get("a2").getSlowConsumerCheckPeriod());
assertEquals(SlowConsumerPolicy.KILL, conf.getAddressesSettings().get("a2").getSlowConsumerPolicy());
assertEquals(false, conf.getAddressesSettings().get("a2").isAutoCreateJmsQueues());
assertEquals(false, conf.getAddressesSettings().get("a2").isAutoDeleteJmsQueues());
assertEquals(2, conf.getQueueConfigurations().size());

View File

@ -42,7 +42,6 @@ import org.apache.activemq.core.message.BodyEncoder;
import org.apache.activemq.core.paging.PagingStore;
import org.apache.activemq.core.paging.cursor.PageSubscription;
import org.apache.activemq.core.server.Consumer;
import org.apache.activemq.core.server.ActiveMQServer;
import org.apache.activemq.core.server.MessageReference;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.core.server.RoutingContext;
@ -1053,6 +1052,12 @@ public class ScheduledDeliveryHandlerTest extends Assert
return false;
}
@Override
public boolean isAutoCreated()
{
return false;
}
@Override
public void addConsumer(Consumer consumer) throws Exception
{
@ -1072,7 +1077,7 @@ public class ScheduledDeliveryHandlerTest extends Assert
}
@Override
public void setConsumersRefCount(ActiveMQServer server)
public void setConsumersRefCount(ReferenceCounter referenceCounter)
{
}
@ -1483,9 +1488,9 @@ public class ScheduledDeliveryHandlerTest extends Assert
}
@Override
public List<MessageReference> cancelScheduledMessages()
public void deliverScheduledMessages()
{
return null;
}
@Override

View File

@ -46,7 +46,8 @@ public class AddressSettingsTest extends UnitTestCase
Assert.assertEquals(AddressSettings.DEFAULT_SLOW_CONSUMER_THRESHOLD, addressSettings.getSlowConsumerThreshold());
Assert.assertEquals(AddressSettings.DEFAULT_SLOW_CONSUMER_CHECK_PERIOD, addressSettings.getSlowConsumerCheckPeriod());
Assert.assertEquals(AddressSettings.DEFAULT_SLOW_CONSUMER_POLICY, addressSettings.getSlowConsumerPolicy());
Assert.assertEquals(AddressSettings.DEFAULT_AUTO_CREATE_QUEUES, addressSettings.isAutoCreateJmsQueues());
Assert.assertEquals(AddressSettings.DEFAULT_AUTO_DELETE_QUEUES, addressSettings.isAutoDeleteJmsQueues());
}
@Test

View File

@ -972,7 +972,7 @@ public abstract class ServiceTestBase extends UnitTestCase
protected HashMap<Integer, AtomicInteger> countJournal(Configuration config) throws Exception
{
final HashMap<Integer, AtomicInteger> recordsType = new HashMap<Integer, AtomicInteger>();
SequentialFileFactory messagesFF = new NIOSequentialFileFactory(getJournalDir(), null);
SequentialFileFactory messagesFF = new NIOSequentialFileFactory(config.getJournalDirectory(), null);
JournalImpl messagesJournal = new JournalImpl(config.getJournalFileSize(),
config.getJournalMinFiles(),

View File

@ -271,6 +271,8 @@
<slow-consumer-threshold>10</slow-consumer-threshold>
<slow-consumer-check-period>5</slow-consumer-check-period>
<slow-consumer-policy>NOTIFY</slow-consumer-policy>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-delete-jms-queues>true</auto-delete-jms-queues>
</address-setting>
<address-setting match="a2">
<dead-letter-address>a2.1</dead-letter-address>
@ -283,6 +285,8 @@
<slow-consumer-threshold>20</slow-consumer-threshold>
<slow-consumer-check-period>15</slow-consumer-check-period>
<slow-consumer-policy>KILL</slow-consumer-policy>
<auto-create-jms-queues>false</auto-create-jms-queues>
<auto-delete-jms-queues>false</auto-delete-jms-queues>
</address-setting>
</address-settings>
<connector-services>

View File

@ -20,10 +20,10 @@ on your client classpath.
## JMS Client
If you are using JMS on the client side, then you will also need to
include `activemq-jms-client.jar` and `jboss-jms-api.jar`.
include `activemq-jms-client.jar` and `geronimo-jms_2.0_spec.jar`.
> **Note**
>
> `jboss-jms-api.jar` just contains Java EE API interface classes needed
> `geronimo-jms_2.0_spec.jar` just contains Java EE API interface classes needed
> for the `javax.jms.*` classes. If you already have a jar with these
> interface classes on your classpath, you will not need it.

View File

@ -95,6 +95,8 @@ entry that would be found in the `activemq-configuration.xml` file.
<slow-consumer-threshold>-1</slow-consumer-threshold>
<slow-consumer-policy>NOTIFY</slow-consumer-policy>
<slow-consumer-check-period>5</slow-consumer-check-period>
<auto-create-queues>true</auto-create-queues>
<auto-delete-queues>true</auto-delete-queues>
</address-setting>
</address-settings>
@ -176,3 +178,13 @@ on this notification.
`slow-consumer-check-period`. How often to check for slow consumers on a
particular queue. Measured in minutes. Default is 5. See ? for more
information about slow consumer detection.
`auto-create-jms-queues`. Whether or not the broker should automatically
create a JMS queue when a JMS message is sent to a queue whose name fits
the address `match` (remember, a JMS queue is just a core queue which has
the same address and queue name) or a JMS consumer tries to connect to a
queue whose name fits the address `match`. Queues which are auto-created
are durable, non-temporary, and non-transient.
`auto-delete-jms-queues`. Whether or not to the broker should automatically
delete auto-created JMS queues when they have both 0 consumers and 0 messages.

View File

@ -52,11 +52,6 @@ under the License.
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>

View File

@ -52,11 +52,6 @@ under the License.
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>

View File

@ -48,11 +48,6 @@ under the License.
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>activemq-jms-examples-common</artifactId>
@ -128,11 +123,6 @@ under the License.
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
</dependency>
</dependencies>
</plugin>
</plugins>

View File

@ -57,9 +57,8 @@ under the License.
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
@ -158,11 +157,6 @@ under the License.
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>

View File

@ -54,10 +54,6 @@ under the License.
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-ejb_3.0_spec</artifactId>
</exclusion>
<exclusion>
<groupId>jboss.jbossts.jts</groupId>
<artifactId>jbossjts-jacorb</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View File

@ -140,7 +140,6 @@ under the License.
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
<version>${geronimo.jms.2.spec.version}</version>
</dependency>
</dependencies>
<configuration>

View File

@ -30,7 +30,7 @@ under the License.
<applet code="org.apache.activemq.jms.example.AppletExample.class"
codebase="build/classes/"
archive="activemq-core-client.jar,activemq-jms-client.jar,jboss-jms-api.jar,netty.jar"
archive="activemq-core-client.jar,activemq-jms-client.jar,geronimo-jms_2.0_spec.jar,netty.jar"
width="640" height="480"></applet>
</body>
</html>

View File

@ -70,8 +70,6 @@ under the License.
<goal>start</goal>
</goals>
<configuration>
<jndiPort>1199</jndiPort>
<jndiRmiPort>1198</jndiRmiPort>
<configurationDir>${basedir}/target/classes/activemq/server1</configurationDir>
<fork>true</fork>
</configuration>

View File

@ -57,7 +57,6 @@ public class EmbeddedExample extends ActiveMQExample
System.out.println("Started Embedded JMS Server");
JMSServerManager jmsServerManager = jmsServer.getJMSServerManager();
jmsServerManager.addQueueToJndi("exampleQueue", "queue/exampleQueue");
List<String> connectors = new ArrayList<String>();
connectors.add("in-vm");
jmsServerManager.createConnectionFactory("ConnectionFactory", false, JMSFactoryType.CF, connectors, "ConnectionFactory");

View File

@ -71,8 +71,6 @@ under the License.
<goal>start</goal>
</goals>
<configuration>
<jndiPort>1199</jndiPort>
<jndiRmiPort>1198</jndiRmiPort>
<configurationDir>${basedir}/target/classes/activemq/server1</configurationDir>
<fork>true</fork>
<systemProperties>

View File

@ -118,7 +118,12 @@ under the License.
InitialContext sourceContext = createContext(sourceServer);
InitialContext targetContext = createContext(targetServer);
</pre>
<li>We then create a JMS Bridge and start it, Note, the Bridge needs a transaction manager, in this instance we will use the JBoss TM</li>
<li>We then create a JMS Bridge and start it, Note, for certain quality of service modes such as
ONCE_AND_ONCE_ONLY and AT_LEAST_ONCE a Transaction Manager is required to ensure Messages are delivered
accordingly. A Transaction Manager can be either loaded via implementation of TransactionManagerLocator intefer
and loaded via standard a ServiceLoader or by explicitly setting an instance of a Transaction Manager on the
bridge using setTranscationManager(TransactionManager tm) method. In this example we'll be using the DUPLICATES_OK
quality of service so there is no need for a Transaction Manager.
<pre class="prettyprint">
JMSBridge jmsBridge = new JMSBridgeImpl(
new JNDIConnectionFactoryFactory(sourceJndiParams, "source/ConnectionFactory"),
@ -132,13 +137,12 @@ under the License.
null,
5000,
10,
QualityOfServiceMode.ONCE_AND_ONLY_ONCE,
QualityOfServiceMode.DUPLICATES_OK,
1,
-1,
null,
null,
true);
jmsBridge.setTransactionManager(new TransactionManagerImple());
....
jmsBridge.start();
</pre>

View File

@ -16,7 +16,6 @@
*/
package org.apache.activemq.jms.example;
import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple;
import org.apache.activemq.jms.bridge.JMSBridge;
import org.apache.activemq.jms.bridge.QualityOfServiceMode;
import org.apache.activemq.jms.bridge.impl.JMSBridgeImpl;
@ -77,13 +76,12 @@ public class JMSBridgeExample
null,
5000,
10,
QualityOfServiceMode.ONCE_AND_ONLY_ONCE,
QualityOfServiceMode.DUPLICATES_OK,
1,
-1,
null,
null,
true);
jmsBridge.setTransactionManager(new TransactionManagerImple());
Connection sourceConnection = null;
Connection targetConnection = null;

View File

@ -49,9 +49,8 @@ under the License.
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq.examples.jms</groupId>
@ -129,9 +128,8 @@ under the License.
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
</dependencies>
</plugin>

View File

@ -128,7 +128,6 @@ under the License.
<module>xa-heuristic</module>
<module>xa-receive</module>
<module>xa-send</module>
<module>xa-with-jta</module>
</modules>
</profile>
<profile>

View File

@ -48,11 +48,6 @@ under the License.
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
@ -130,9 +125,8 @@ under the License.
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-jms-api</artifactId>
<version>1.1.0.GA</version>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
</dependencies>
</plugin>

View File

@ -75,8 +75,6 @@ under the License.
<goal>start</goal>
</goals>
<configuration>
<jndiPort>1199</jndiPort>
<jndiRmiPort>1198</jndiRmiPort>
<configurationDir>${basedir}/target/classes/activemq/server1</configurationDir>
<fork>true</fork>
<systemProperties>

View File

@ -82,8 +82,10 @@ public class SymmetricClusterExample extends ActiveMQExample
// connection factory directly we avoid having to worry about a JNDI look-up.
// In an app server environment you could use HA-JNDI to lookup from the clustered JNDI servers without
// having to know about a specific one.
UDPBroadcastGroupConfiguration udpCfg = new UDPBroadcastGroupConfiguration("231.7.7.7", 9876, null, -1);
DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration(ActiveMQClient.DEFAULT_DISCOVERY_INITIAL_WAIT_TIMEOUT, ActiveMQClient.DEFAULT_DISCOVERY_INITIAL_WAIT_TIMEOUT, udpCfg);
UDPBroadcastGroupConfiguration udpCfg = new UDPBroadcastGroupConfiguration();
udpCfg.setGroupAddress("231.7.7.7").setGroupPort(9876);
DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration();
groupConfiguration.setBroadcastEndpointFactoryConfiguration(udpCfg);
ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactoryWithHA(groupConfiguration, JMSFactoryType.CF);

View File

@ -42,11 +42,6 @@ under the License.
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.jbossts.jts</groupId>
<artifactId>jbossjts-jacorb</artifactId>
<version>4.17.4.Final</version>
</dependency>
</dependencies>
<build>

View File

@ -1,142 +0,0 @@
<?xml version='1.0'?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>jms-examples</artifactId>
<version>6.0.0-SNAPSHOT</version>
</parent>
<artifactId>activemq-jms-xa-with-jta-example</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ6 JMS XA with JTA Example</name>
<dependencies>
<dependency>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>activemq-jms-examples-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-ejb_3.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.jbossts</groupId>
<artifactId>jbossjta</artifactId>
<version>4.16.4.Final</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-maven-plugin</artifactId>
<executions>
<execution>
<id>start</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<systemProperties>
<property>
<name>build.directory</name>
<value>${basedir}/target/</value>
</property>
</systemProperties>
</configuration>
</execution>
<execution>
<id>runClient</id>
<goals>
<goal>runClient</goal>
</goals>
<configuration>
<clientClass>org.apache.activemq.jms.example.XAwithJTAExample</clientClass>
</configuration>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>activemq-jms-xa-with-jta-example</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
<version>${geronimo.jms.2.spec.version}</version>
</dependency>
</dependencies>
<configuration>
<waitOnStart>false</waitOnStart>
<configurationDir>${basedir}/target/classes/activemq/server0</configurationDir>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,220 +0,0 @@
<!--
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.
-->
<html>
<head>
<title>ActiveMQ JMS XA with JTA Example</title>
<link rel="stylesheet" type="text/css" href="../common/common.css" />
<link rel="stylesheet" type="text/css" href="../common/prettify.css" />
<script type="text/javascript" src="../common/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<h1>JMS XA with JTA Example</h1>
<p>This example shows you how to use JTA interfaces to control transactions with ActiveMQ. JTA provides
facilities to start and stop a transaction and enlist XA resources into a transaction.</p>
<p>ActiveMQ is JTA aware, meaning you can use ActiveMQ in a XA transactional environment
and participate in XA transactions. It provides the javax.transaction.xa.XAResource interface for that
purpose. Users can get a XAConnectionFactory to create XAConnections and XASessions.</p>
<p>In this example we get a transaction manager from JBoss JTA to control the transactions. First we create an XASession
for receiving and a normal session for sending. Then we start a new xa transaction and enlist the receiving
XASession through its XAResource. We then send two words, 'hello' and 'world', receive them, and let the
transaction roll back. The received messages are cancelled back to the queue. Next we start
a new transaction with the same XAResource enlisted, but this time we commit the transaction after receiving the
messages. Then we check that no more messages are to be received. In each transaction a dummy XAResource is also
enlisted to show the transaction processing information.</p>
<h2>Example step-by-step</h2>
<p><i>To run the example, simply type <code>mvn verify</code> from this directory. It will download the JBoss JTA jars before
it launches the example.</i></p>
<ol>
<li>First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the <code>client-jndi.properties</code> file in the directory <code>../common/config</code></li>
<pre class="prettyprint">
<code>InitialContext initialContext = getContext(0);</code>
</pre>
<li>We look-up the JMS queue object from JNDI</li>
<pre class="prettyprint">
<code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code>
</pre>
<li>We perform a lookup on the XA Connection Factory</li>
<pre class="prettyprint">
<code>XAConnectionFactory cf = (XAConnectionFactory) initialContext.lookup("/XAConnectionFactory");</code>
</pre>
<li>We create a JMS XAConnection</li>
<pre class="prettyprint">
<code>connection = cf.createXAConnection();</code>
</pre>
<li>We Start the connection</li>
<pre class="prettyprint">
<code>connection.start();</code>
</pre>
<li>We create a JMS XASession</li>
<pre class="prettyprint">
<code>XASession xaSession = connection.createXASession();</code>
</pre>
<li>We create a normal session</li>
<pre class="prettyprint">
<code>Session normalSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code>
</pre>
<li>We create a normal Message Producer</li>
<pre class="prettyprint">
<code>
MessageProducer normalProducer = normalSession.createProducer(queue);
</code>
</pre>
<li>We get the JMS Session</li>
<pre class="prettyprint">
<code>Session session = xaSession.getSession();</code>
</pre>
<li>We create a message consumer</li>
<pre class="prettyprint">
<code>MessageConsumer xaConsumer = session.createConsumer(queue); </code>
</pre>
<li>We create two Text Messages</li>
<pre class="prettyprint">
<code>
TextMessage helloMessage = session.createTextMessage("hello");
TextMessage worldMessage = session.createTextMessage("world");
</code>
</pre>
<li>We get the Transaction Manager</li>
<pre class="prettyprint">
<code>javax.transaction.TransactionManager txMgr = TransactionManager.transactionManager();</code>
</pre>
<li>We start a transaction</li>
<pre class="prettyprint">
<code>txMgr.begin();</code>
</pre>
<li>We get the JMS XAResource</li>
<pre class="prettyprint">
<code>XAResource xaRes = xaSession.getXAResource();</code>
</pre>
<li>We enlist the resources in the Transaction work</li>
<pre class="prettyprint">
<code>
Transaction transaction = txMgr.getTransaction();
transaction.enlistResource(new DummyXAResource());
transaction.enlistResource(xaRes);
</code>
</pre>
<li>We send two messages.</li>
<pre class="prettyprint">
<code>
normalProducer.send(helloMessage);
normalProducer.send(worldMessage);
</code>
</pre>
<li>We receive the messages</li>
<pre class="prettyprint">
<code>
TextMessage rm1 = (TextMessage)xaConsumer.receive();
System.out.println("Message received: " + rm1.getText());
TextMessage rm2 = (TextMessage)xaConsumer.receive();
System.out.println("Message received: " + rm2.getText());
</code>
</pre>
<li>We roll back the transaction</li>
<pre class="prettyprint">
<code>txMgr.rollback();</code>
</pre>
<li>We create another transaction </li>
<pre class="prettyprint">
<code>
txMgr.begin();
transaction = txMgr.getTransaction();
</code>
</pre>
<li>We enlist the resources to start the transaction work</li>
<pre class="prettyprint">
<code>
transaction.enlistResource(new DummyXAResource());
transaction.enlistResource(xaRes);
</code>
</pre>
<li>We receive those messages again</li>
<pre class="prettyprint">
<code>
rm1 = (TextMessage)xaConsumer.receive();
System.out.println("Message received again: " + rm1.getText());
rm2 = (TextMessage)xaConsumer.receive();
System.out.println("Message received again: " + rm2.getText());
</code>
</pre>
<li>We commit</li>
<pre class="prettyprint">
<code>txMgr.commit();</code>
</pre>
<li>We check that no more messages are received.</li>
<pre class="prettyprint">
<code>
TextMessage rm3 = (TextMessage)xaConsumer.receive(2000);
if (rm3 == null)
{
System.out.println("No message received after commit.");
}
else
{
result = false;
}
</code>
</pre>
<li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li>
<pre class="prettyprint">
<code>finally
{
if (initialContext != null)
{
initialContext.close();
}
if (connection != null)
{
connection.close();
}
}</code>
</pre>
</ol>
</body>
</html>

View File

@ -1,222 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.jms.example;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.XAConnection;
import javax.jms.XAConnectionFactory;
import javax.jms.XASession;
import javax.naming.InitialContext;
import javax.transaction.Transaction;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import com.arjuna.ats.jta.TransactionManager;
import org.apache.activemq.common.example.ActiveMQExample;
/**
* A simple JMS example showing the ActiveMQ XA support with JTA.
*
* @author <a href="hgao@redhat.com">Howard Gao</a>
*/
public class XAwithJTAExample extends ActiveMQExample
{
private volatile boolean result = true;
public static void main(final String[] args)
{
new XAwithJTAExample().run(args);
}
@Override
public boolean runExample() throws Exception
{
XAConnection connection = null;
InitialContext initialContext = null;
try
{
// Step 1. Create an initial context to perform the JNDI lookup.
initialContext = new InitialContext();
// Step 2. Lookup on the queue
Queue queue = (Queue)initialContext.lookup("queue/exampleQueue");
// Step 3. Perform a lookup on the XA Connection Factory
XAConnectionFactory cf = (XAConnectionFactory)initialContext.lookup("XAConnectionFactory");
// Step 4.Create a JMS XAConnection
connection = cf.createXAConnection();
// Step 5. Start the connection
connection.start();
// Step 6. Create a JMS XASession
XASession xaSession = connection.createXASession();
// Step 7. Create a normal session
Session normalSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Step 8. Create a normal Message Producer
MessageProducer normalProducer = normalSession.createProducer(queue);
// Step 9. Get the JMS Session
Session session = xaSession.getSession();
// Step 10. Create a message consumer
MessageConsumer xaConsumer = session.createConsumer(queue);
// Step 11. Create two Text Messages
TextMessage helloMessage = session.createTextMessage("hello");
TextMessage worldMessage = session.createTextMessage("world");
// Step 12. Get the Transaction Manager
javax.transaction.TransactionManager txMgr = TransactionManager.transactionManager();
// Step 13. Start a transaction
txMgr.begin();
// Step 14. Get the JMS XAResource
XAResource xaRes = xaSession.getXAResource();
// Step 15. enlist the resource in the Transaction work
Transaction transaction = txMgr.getTransaction();
transaction.enlistResource(new DummyXAResource());
transaction.enlistResource(xaRes);
// Step 16. Send two messages.
normalProducer.send(helloMessage);
normalProducer.send(worldMessage);
// Step 17. Receive the message
TextMessage rm1 = (TextMessage)xaConsumer.receive();
System.out.println("Message received: " + rm1.getText());
TextMessage rm2 = (TextMessage)xaConsumer.receive();
System.out.println("Message received: " + rm2.getText());
// Step 18. Roll back the transaction
txMgr.rollback();
// Step 19. Create another transaction
txMgr.begin();
transaction = txMgr.getTransaction();
// Step 20. Enlist the resources to start the transaction work
transaction.enlistResource(new DummyXAResource());
transaction.enlistResource(xaRes);
// Step 21. receive those messages again
rm1 = (TextMessage)xaConsumer.receive();
System.out.println("Message received again: " + rm1.getText());
rm2 = (TextMessage)xaConsumer.receive();
System.out.println("Message received again: " + rm2.getText());
// Step 22. Commit!
txMgr.commit();
// Step 23. Check no more messages are received.
TextMessage rm3 = (TextMessage)xaConsumer.receive(2000);
if (rm3 == null)
{
System.out.println("No message received after commit.");
}
else
{
result = false;
}
return result;
}
finally
{
// Step 24. Be sure to close our JMS resources!
if (initialContext != null)
{
initialContext.close();
}
if (connection != null)
{
connection.close();
}
}
}
public static class DummyXAResource implements XAResource
{
public DummyXAResource()
{
}
public void commit(final Xid xid, final boolean arg1) throws XAException
{
System.out.println("DummyXAResource commit() called, xid: " + xid);
}
public void end(final Xid xid, final int arg1) throws XAException
{
System.out.println("DummyXAResource end() called, xid: " + xid);
}
public void forget(final Xid xid) throws XAException
{
System.out.println("DummyXAResource forget() called, xid: " + xid);
}
public int getTransactionTimeout() throws XAException
{
return 0;
}
public boolean isSameRM(final XAResource arg0) throws XAException
{
return this == arg0;
}
public int prepare(final Xid xid) throws XAException
{
return XAResource.XA_OK;
}
public Xid[] recover(final int arg0) throws XAException
{
return null;
}
public void rollback(final Xid xid) throws XAException
{
System.out.println("DummyXAResource rollback() called, xid: " + xid);
}
public boolean setTransactionTimeout(final int arg0) throws XAException
{
return false;
}
public void start(final Xid xid, final int arg1) throws XAException
{
System.out.println("DummyXAResource start() called, Xid: " + xid);
}
}
}

View File

@ -1,54 +0,0 @@
<?xml version='1.0'?>
<!--
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.
-->
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq /schema/activemq-configuration.xsd">
<bindings-directory>${build.directory}/server0/data/messaging/bindings</bindings-directory>
<journal-directory>${build.directory}/server0/data/messaging/journal</journal-directory>
<large-messages-directory>${build.directory}/server0/data/messaging/largemessages</large-messages-directory>
<paging-directory>${build.directory}/server0/data/messaging/paging</paging-directory>
<!-- Acceptors -->
<acceptors>
<acceptor name="netty-acceptor">
<factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
</acceptor>
</acceptors>
<!-- Other config -->
<security-settings>
<!--security for example queue-->
<security-setting match="jms.queue.exampleQueue">
<permission type="createDurableQueue" roles="guest"/>
<permission type="deleteDurableQueue" roles="guest"/>
<permission type="createNonDurableQueue" roles="guest"/>
<permission type="deleteNonDurableQueue" roles="guest"/>
<permission type="consume" roles="guest"/>
<permission type="send" roles="guest"/>
</security-setting>
</security-settings>
</configuration>

View File

@ -1,28 +0,0 @@
<?xml version='1.0'?>
<!--
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.
-->
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq /schema/activemq-jms.xsd">
<!--the queue used by the example-->
<queue name="exampleQueue"/>
</configuration>

View File

@ -1,27 +0,0 @@
<?xml version='1.0'?>
<!--
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.
-->
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq /schema/activemq-users.xsd">
<!-- the default user. this is used where username is null-->
<defaultuser name="guest" password="guest">
<role name="guest"/>
</defaultuser>
</configuration>

View File

@ -1,175 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!--
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.
-->
<properties>
<!--
This is the JBossTS configuration file for running ArjunaJTS.
It should be called jbossts-properties.xml.
You need a different version for ArjunaCore or JTA usage.
***************************
Property values may be literals or be tokens of the form ${p1[,p2][:v]}
in which case the token values are substituted for the values of the corresponding system
properties as follows:
- Any occurrence of ${p} with the System.getProperty(p) value.
If there is no such property p defined, then the ${p} reference will remain unchanged.
- If the property reference is of the form ${p:v} and there is no such property p,
then the default value v will be returned.
- If the property reference is of the form ${p1,p2} or ${p1,p2:v} then
the primary and the secondary properties will be tried in turn, before
returning either the unchanged input, or the default value.
The property ${/} is replaced with System.getProperty("file.separator")
value and the property ${:} is replaced with System.getProperty("path.separator").
Note this substitution applies to property values only at the point they are read from
the config file. Tokens in system properties won't be substituted.
-->
<!-- (default is YES) -->
<entry key="CoordinatorEnvironmentBean.commitOnePhase">YES</entry>
<!-- default is under user.home - must be writeable!) -->
<entry key="ObjectStoreEnvironmentBean.objectStoreDir">PutObjectStoreDirHere</entry>
<!-- (default is ON) -->
<entry key="ObjectStoreEnvironmentBean.transactionSync">ON</entry>
<!-- (Must be unique across all Arjuna instances.) -->
<entry key="CoreEnvironmentBean.nodeIdentifier">1</entry>
<!-- Which Xid types to recover -->
<entry key="JTAEnvironmentBean.xaRecoveryNodes">1</entry>
<entry key="JTAEnvironmentBean.xaResourceOrphanFilterClassNames">
com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter
com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter
</entry>
<!--
Base port number for determining a unique number to associate with an instance of the transaction service
(which is needed in order to support multiple instances on the same machine).
Use the value 0 to allow the system to select the first available port number.
If the port number is non-zero and the port is in use then the value will be incremented until either a successful binding
to the loopback address is created or until the the maximum number of ports (specified by the
CoreEnvironmentBean.socketProcessIdMaxPorts property) have been tried or until the port number
reaches the maximum possible port number.
-->
<entry key="CoreEnvironmentBean.socketProcessIdPort">0</entry>
<!--
Periodic recovery modules to use. Invoked in the order they appear in the list.
Check http://www.jboss.org/community/docs/DOC-10788 for more information
on recovery modules and their configuration when running in various
deployments.
-->
<entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
com.arjuna.ats.internal.jts.recovery.transactions.TopLevelTransactionRecoveryModule
com.arjuna.ats.internal.jts.recovery.transactions.ServerTransactionRecoveryModule
com.arjuna.ats.internal.jta.recovery.jts.XARecoveryModule
</entry>
<!-- Expiry scanners to use (order of invocation is random). -->
<entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
com.arjuna.ats.internal.jts.recovery.contact.ExpiredContactScanner
com.arjuna.ats.internal.jts.recovery.transactions.ExpiredToplevelScanner
com.arjuna.ats.internal.jts.recovery.transactions.ExpiredServerScanner
</entry>
<!--
Add the following to the set of expiryScannerClassNames above to move logs that cannot be completed by failure recovery.
But be sure you know what you are doing and why!
com.arjuna.ats.internal.arjuna.recovery.AtomicActionExpiryScanner
-->
<!--
The address and port number on which the recovery manager listens
If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
-->
<entry key="RecoveryEnvironmentBean.recoveryPort">4712</entry>
<entry key="RecoveryEnvironmentBean.recoveryAddress"></entry>
<!--
Use this to fix the port on which the TransactionStatusManager listens,
The default behaviour is to use any free port.
-->
<entry key="RecoveryEnvironmentBean.transactionStatusManagerPort">0</entry>
<!--
Use this to fix the address on which the TransactionStatusManager binds,
The default behaviour is to use the loopback address (ie localhost).
If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
-->
<entry key="RecoveryEnvironmentBean.transactionStatusManagerAddress"></entry>
<!--
For cases where the recovery manager is in process with the transaction manager and nothing else uses
the ObjectStore, it is possible to disable the socket based recovery listener by setting this to NO.
Caution: use of this property can allow multiple recovery processes to run on the same ObjectStore
if you are not careful. That in turn can lead to incorrect transaction processing. Use with care.
-->
<entry key="RecoveryEnvironmentBean.recoveryListener">YES</entry>
<!-- Recovery Activators to use. -->
<entry key="RecoveryEnvironmentBean.recoveryActivatorClassNames">com.arjuna.ats.internal.jts.orbspecific.recovery.RecoveryEnablement</entry>
<entry key="JTAEnvironmentBean.transactionManagerClassName">com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple</entry>
<entry key="JTAEnvironmentBean.userTransactionClassName">com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple</entry>
<entry key="JTAEnvironmentBean.transactionSynchronizationRegistryClassName">com.arjuna.ats.internal.jta.transaction.jts.TransactionSynchronizationRegistryImple</entry>
<entry key="OrbPortabilityEnvironmentBean.bindMechanism">CONFIGURATION_FILE</entry>
<entry key="OrbPortabilityEnvironmentBean.orbInitializationProperties">
<!-- This class handles context propagation issues, and should never be commented out or removed. -->
com.arjuna.orbportability.orb.PreInit1=com.arjuna.ats.internal.jts.context.ContextPropagationManager
<!-- This property ensures the JTS knows which ORB to use and should never be commented out or removed -->
com.arjuna.orbportability.orb.PostInit=com.arjuna.ats.jts.utils.ORBSetup
<!-- This property ensures the crash recovery is initialised correctly and should never be commented out or removed -->
com.arjuna.orbportability.orb.PostInit2=com.arjuna.ats.internal.jts.recovery.RecoveryInit
<!-- This property ensures the JTS knows which ORB to use and should never be commented out or removed -->
com.arjuna.orbportability.orb.PostSet1=com.arjuna.ats.jts.utils.ORBSetup
</entry>
<!--
This property controls the port on which the Recovery ORB listens
-->
<entry key="JTSEnvironmentBean.recoveryManagerPort">4711</entry>
<!--
This property controls the address on which the Recovery ORB binds - defaults to the loopback connection
If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
-->
<entry key="JTSEnvironmentBean.recoveryManagerAddress"></entry>
</properties>

View File

@ -1,20 +0,0 @@
# 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.
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:5445
queue.queue/exampleQueue=exampleQueue

View File

@ -49,7 +49,7 @@
<activemq.version.majorVersion>6</activemq.version.majorVersion>
<activemq.version.minorVersion>0</activemq.version.minorVersion>
<activemq.version.microVersion>0</activemq.version.microVersion>
<activemq.version.incrementingVersion>125,124,123,122</activemq.version.incrementingVersion>
<activemq.version.incrementingVersion>126,125,124,123,122</activemq.version.incrementingVersion>
<activemq.version.versionSuffix>SNAPSHOT</activemq.version.versionSuffix>
<activemq.version.versionTag>SNAPSHOT</activemq.version.versionTag>
<ActiveMQ-Version>
@ -414,7 +414,7 @@
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
<releases>
@ -916,6 +916,7 @@
<exclude>etc/org.eclipse.*</exclude>
<exclude>docs/user-manual/en/*.json</exclude>
<exclude>**/target/</exclude>
<exclude>**/data/</exclude>
<exclude>**/*.bindings</exclude>
<exclude>**/*.lock</exclude>
<exclude>**/META-INF/services/*</exclude>

View File

@ -77,6 +77,7 @@ public class QueueTest extends UnitTestCase
null,
null,
false,
false,
false);
FakeConsumer consumer = new FakeConsumer();

View File

@ -0,0 +1,187 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tests.integration.client;
import javax.jms.Connection;
import javax.jms.InvalidDestinationException;
import javax.jms.JMSSecurityException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import java.util.HashSet;
import java.util.Set;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.api.jms.ActiveMQJMSClient;
import org.apache.activemq.core.security.Role;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.tests.util.JMSTestBase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Justin Bertram
*/
public class AutoCreateJmsQueueTest extends JMSTestBase
{
@Test
public void testAutoCreateOnSendToQueue() throws Exception
{
Connection connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.Queue queue = ActiveMQJMSClient.createQueue("test");
MessageProducer producer = session.createProducer(queue);
final int numMessages = 100;
for (int i = 0; i < numMessages; i++)
{
TextMessage mess = session.createTextMessage("msg" + i);
producer.send(mess);
}
producer.close();
MessageConsumer messageConsumer = session.createConsumer(queue);
connection.start();
for (int i = 0; i < numMessages; i++)
{
Message m = messageConsumer.receive(5000);
Assert.assertNotNull(m);
}
connection.close();
}
@Test
public void testAutoCreateOnSendToQueueSecurity() throws Exception
{
server.getSecurityManager().addUser("guest", "guest");
server.getSecurityManager().setDefaultUser("guest");
server.getSecurityManager().addRole("guest", "rejectAll");
Role role = new Role("rejectAll", false, false, false, false, false, false, false);
Set<Role> roles = new HashSet<Role>();
roles.add(role);
server.getSecurityRepository().addMatch("#", roles);
Connection connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.Queue queue = ActiveMQJMSClient.createQueue("test");
try
{
MessageProducer producer = session.createProducer(queue);
Assert.fail("Creating a producer here should throw a JMSSecurityException");
}
catch (Exception e)
{
Assert.assertTrue(e instanceof JMSSecurityException);
}
connection.close();
}
@Test
public void testAutoCreateOnSendToTopic() throws Exception
{
Connection connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.Topic topic = ActiveMQJMSClient.createTopic("test");
try
{
MessageProducer producer = session.createProducer(topic);
Assert.fail("Creating a producer here should throw an exception");
}
catch (Exception e)
{
Assert.assertTrue(e instanceof InvalidDestinationException);
}
connection.close();
}
@Test
public void testAutoCreateOnConsumeFromQueue() throws Exception
{
Connection connection = null;
connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.Queue queue = ActiveMQJMSClient.createQueue("test");
MessageConsumer messageConsumer = session.createConsumer(queue);
connection.start();
Message m = messageConsumer.receive(500);
Assert.assertNull(m);
Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString("jms.queue.test")).getBindable();
Assert.assertEquals(0, q.getMessageCount());
Assert.assertEquals(0, q.getMessagesAdded());
connection.close();
}
@Test
public void testAutoCreateOnConsumeFromTopic() throws Exception
{
Connection connection = null;
connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.Topic topic = ActiveMQJMSClient.createTopic("test");
try
{
MessageConsumer messageConsumer = session.createConsumer(topic);
Assert.fail("Creating a consumer here should throw an exception");
}
catch (Exception e)
{
Assert.assertTrue(e instanceof InvalidDestinationException);
}
connection.close();
}
@Before
@Override
public void setUp() throws Exception
{
super.setUp();
server.getSecurityManager().addUser("guest", "guest");
server.getSecurityManager().setDefaultUser("guest");
server.getSecurityManager().addRole("guest", "allowAll");
Role role = new Role("allowAll", true, true, true, true, true, true, true);
Set<Role> roles = new HashSet<Role>();
roles.add(role);
server.getSecurityRepository().addMatch("#", roles);
}
protected boolean useSecurity()
{
return true;
}
}

View File

@ -0,0 +1,84 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tests.integration.client;
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.api.jms.ActiveMQJMSClient;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.tests.util.JMSTestBase;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Justin Bertram
*/
public class AutoDeleteJmsQueueTest extends JMSTestBase
{
@Test
public void testAutoDelete() throws Exception
{
Connection connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.Queue queue = ActiveMQJMSClient.createQueue("test");
MessageProducer producer = session.createProducer(queue);
final int numMessages = 100;
for (int i = 0; i < numMessages; i++)
{
TextMessage mess = session.createTextMessage("msg" + i);
producer.send(mess);
}
producer.close();
MessageConsumer messageConsumer = session.createConsumer(queue);
connection.start();
for (int i = 0; i < numMessages - 1; i++)
{
Message m = messageConsumer.receive(5000);
Assert.assertNotNull(m);
}
session.close();
// ensure the queue is still there
Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString("jms.queue.test")).getBindable();
Assert.assertEquals(1, q.getMessageCount());
Assert.assertEquals(numMessages, q.getMessagesAdded());
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
messageConsumer = session.createConsumer(queue);
Message m = messageConsumer.receive(5000);
Assert.assertNotNull(m);
connection.close();
// ensure the queue was removed
Assert.assertNull(server.getPostOffice().getBinding(new SimpleString("jms.queue.test")));
}
}

View File

@ -16,7 +16,6 @@
*/
package org.apache.activemq.tests.integration.client;
import org.apache.activemq.api.core.ActiveMQException;
import org.apache.activemq.core.server.MessageReference;
import org.apache.activemq.core.server.ServerConsumer;
import org.junit.Before;
import org.junit.After;
@ -24,7 +23,6 @@ import org.junit.Test;
import java.lang.management.ManagementFactory;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
@ -244,6 +242,7 @@ public class HangConsumerTest extends ServiceTestBase
final PageSubscription pageSubscription,
final boolean durable,
final boolean temporary,
final boolean autoCreated,
final ScheduledExecutorService scheduledExecutor,
final PostOffice postOffice,
final StorageManager storageManager,
@ -257,6 +256,7 @@ public class HangConsumerTest extends ServiceTestBase
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,
@ -274,9 +274,8 @@ public class HangConsumerTest extends ServiceTestBase
}
@Override
public List<MessageReference> cancelScheduledMessages()
public void deliverScheduledMessages()
{
return null;
}
}
@ -297,7 +296,8 @@ public class HangConsumerTest extends ServiceTestBase
final Filter filter,
final PageSubscription pageSubscription,
final boolean durable,
final boolean temporary)
final boolean temporary,
final boolean autoCreated)
{
queue = new MyQueueWithBlocking(persistenceID,
address,
@ -306,6 +306,7 @@ public class HangConsumerTest extends ServiceTestBase
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,
@ -404,7 +405,7 @@ public class HangConsumerTest extends ServiceTestBase
// Forcing a situation where the server would unexpectedly create a duplicated queue. The server should still start normally
LocalQueueBinding newBinding = new LocalQueueBinding(QUEUE, new QueueImpl(queueID, QUEUE, QUEUE, null, true, false, null, null, null, null, null), server.getNodeID());
LocalQueueBinding newBinding = new LocalQueueBinding(QUEUE, new QueueImpl(queueID, QUEUE, QUEUE, null, true, false, false, null, null, null, null, null), server.getNodeID());
server.getStorageManager().addQueueBinding(txID, newBinding);
server.getStorageManager().commitBindings(txID);

View File

@ -20,7 +20,6 @@ import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
@ -507,6 +506,7 @@ public class InterruptedLargeMessageTest extends LargeMessageTestBase
PageSubscription pageSubscription,
boolean durable,
boolean temporary,
boolean autoCreated,
ScheduledExecutorService scheduledExecutor,
PostOffice postOffice,
StorageManager storageManager,
@ -520,6 +520,7 @@ public class InterruptedLargeMessageTest extends LargeMessageTestBase
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,
@ -534,9 +535,8 @@ public class InterruptedLargeMessageTest extends LargeMessageTestBase
}
@Override
public List<MessageReference> cancelScheduledMessages()
public void deliverScheduledMessages()
{
return null;
}
}
@ -572,7 +572,8 @@ public class InterruptedLargeMessageTest extends LargeMessageTestBase
Filter filter,
PageSubscription pageSubscription,
boolean durable,
boolean temporary)
boolean temporary,
boolean autoCreated)
{
return new NoPostACKQueue(persistenceID,
@ -582,6 +583,7 @@ public class InterruptedLargeMessageTest extends LargeMessageTestBase
pageSubscription,
durable,
temporary,
autoCreated,
scheduledExecutor,
postOffice,
storageManager,

View File

@ -749,7 +749,9 @@ public class PagingOrderTest extends ServiceTestBase
"PAGE",
-1,
10,
"KILL");
"KILL",
true,
true);
ActiveMQJMSConnectionFactory cf = (ActiveMQJMSConnectionFactory) ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,
new TransportConfiguration(INVM_CONNECTOR_FACTORY));
@ -824,7 +826,9 @@ public class PagingOrderTest extends ServiceTestBase
"PAGE",
-1,
10,
"KILL");
"KILL",
true,
true);
jmsServer.createQueue(true, "Q1", null, true, "/queue/Q1");

View File

@ -62,6 +62,7 @@ import org.apache.activemq.core.postoffice.Bindings;
import org.apache.activemq.core.postoffice.PostOffice;
import org.apache.activemq.core.postoffice.QueueBinding;
import org.apache.activemq.core.postoffice.impl.LocalQueueBinding;
import org.apache.activemq.core.protocol.core.impl.CoreProtocolManagerFactory;
import org.apache.activemq.core.remoting.impl.netty.TransportConstants;
import org.apache.activemq.core.server.ActiveMQServer;
import org.apache.activemq.core.server.ActiveMQServers;
@ -1681,7 +1682,8 @@ public abstract class ClusterTestBase extends ServiceTestBase
.setThreadPoolMaxSize(10)
.clearAcceptorConfigurations()
.addAcceptorConfiguration(createTransportConfiguration(netty, true, generateParams(node, netty)))
.setHAPolicyConfiguration(haPolicyConfiguration);
.setHAPolicyConfiguration(haPolicyConfiguration)
.setResolveProtocols(false);
ActiveMQServer server;
@ -1708,6 +1710,8 @@ public abstract class ClusterTestBase extends ServiceTestBase
}
}
server.addProtocolManagerFactory(new CoreProtocolManagerFactory());
server.setIdentity(this.getClass().getSimpleName() + "/Live(" + node + ")");
servers[node] = server;
}

View File

@ -82,7 +82,7 @@ public class TopicCleanupTest extends JMSTestBase
{
long txid = storage.generateID();
final Queue queue = new QueueImpl(storage.generateID(), SimpleString.toSimpleString("jms.topic.topic"), SimpleString.toSimpleString("jms.topic.topic"), FilterImpl.createFilter(ActiveMQServerImpl.GENERIC_IGNORED_FILTER), true, false, server.getScheduledPool(), server.getPostOffice(),
final Queue queue = new QueueImpl(storage.generateID(), SimpleString.toSimpleString("jms.topic.topic"), SimpleString.toSimpleString("jms.topic.topic"), FilterImpl.createFilter(ActiveMQServerImpl.GENERIC_IGNORED_FILTER), true, false, false, server.getScheduledPool(), server.getPostOffice(),
storage, server.getAddressSettingsRepository(), server.getExecutorFactory().getExecutor());
LocalQueueBinding binding = new LocalQueueBinding(queue.getAddress(), queue, server.getNodeID());

View File

@ -62,7 +62,7 @@ public class NonExistentQueueTest extends JMSTestBase
@Test
public void sendToNonExistantDestination() throws Exception
{
Destination destination = ActiveMQJMSClient.createQueue("DoesNotExist");
Destination destination = ActiveMQJMSClient.createTopic("DoesNotExist");
TransportConfiguration transportConfiguration = new TransportConfiguration(InVMConnectorFactory.class.getName());
ConnectionFactory localConnectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,
transportConfiguration);

View File

@ -507,6 +507,8 @@ public class ActiveMQServerControlTest extends ManagementTestBase
long slowConsumerThreshold = 5;
long slowConsumerCheckPeriod = 10;
String slowConsumerPolicy = SlowConsumerPolicy.KILL.toString();
boolean autoCreateJmsQueues = false;
boolean autoDeleteJmsQueues = false;
serverControl.addAddressSettings(addressMatch,
DLA,
@ -525,7 +527,9 @@ public class ActiveMQServerControlTest extends ManagementTestBase
addressFullMessagePolicy,
slowConsumerThreshold,
slowConsumerCheckPeriod,
slowConsumerPolicy);
slowConsumerPolicy,
autoCreateJmsQueues,
autoDeleteJmsQueues);
boolean ex = false;
@ -548,7 +552,9 @@ public class ActiveMQServerControlTest extends ManagementTestBase
addressFullMessagePolicy,
slowConsumerThreshold,
slowConsumerCheckPeriod,
slowConsumerPolicy);
slowConsumerPolicy,
autoCreateJmsQueues,
autoDeleteJmsQueues);
}
catch (Exception expected)
{
@ -578,6 +584,8 @@ public class ActiveMQServerControlTest extends ManagementTestBase
assertEquals(slowConsumerThreshold, info.getSlowConsumerThreshold());
assertEquals(slowConsumerCheckPeriod, info.getSlowConsumerCheckPeriod());
assertEquals(slowConsumerPolicy, info.getSlowConsumerPolicy());
assertEquals(autoCreateJmsQueues, info.isAutoCreateJmsQueues());
assertEquals(autoDeleteJmsQueues, info.isAutoDeleteJmsQueues());
serverControl.addAddressSettings(addressMatch,
DLA,
@ -596,7 +604,9 @@ public class ActiveMQServerControlTest extends ManagementTestBase
addressFullMessagePolicy,
slowConsumerThreshold,
slowConsumerCheckPeriod,
slowConsumerPolicy);
slowConsumerPolicy,
autoCreateJmsQueues,
autoDeleteJmsQueues);
jsonString = serverControl.getAddressSettingsAsJSON(exactAddress);
@ -618,6 +628,8 @@ public class ActiveMQServerControlTest extends ManagementTestBase
assertEquals(slowConsumerThreshold, info.getSlowConsumerThreshold());
assertEquals(slowConsumerCheckPeriod, info.getSlowConsumerCheckPeriod());
assertEquals(slowConsumerPolicy, info.getSlowConsumerPolicy());
assertEquals(autoCreateJmsQueues, info.isAutoCreateJmsQueues());
assertEquals(autoDeleteJmsQueues, info.isAutoDeleteJmsQueues());
ex = false;
@ -640,7 +652,9 @@ public class ActiveMQServerControlTest extends ManagementTestBase
addressFullMessagePolicy,
slowConsumerThreshold,
slowConsumerCheckPeriod,
slowConsumerPolicy);
slowConsumerPolicy,
autoCreateJmsQueues,
autoDeleteJmsQueues);
}
catch (Exception e)
{

View File

@ -582,7 +582,9 @@ public class ActiveMQServerControlUsingCoreTest extends ActiveMQServerControlTes
@Parameter(desc = "the policy to use when the address is full", name = "addressFullMessagePolicy") String addressFullMessagePolicy,
@Parameter(desc = "when a consumer falls below this threshold in terms of messages consumed per second it will be considered 'slow'", name = "slowConsumerThreshold") long slowConsumerThreshold,
@Parameter(desc = "how often (in seconds) to check for slow consumers", name = "slowConsumerCheckPeriod") long slowConsumerCheckPeriod,
@Parameter(desc = "the policy to use when a slow consumer is detected", name = "slowConsumerPolicy") String slowConsumerPolicy) throws Exception
@Parameter(desc = "the policy to use when a slow consumer is detected", name = "slowConsumerPolicy") String slowConsumerPolicy,
@Parameter(desc = "allow queues to be created automatically", name = "autoCreateJmsQueues") boolean autoCreateJmsQueues,
@Parameter(desc = "allow auto-created queues to be deleted automatically", name = "autoDeleteJmsQueues") boolean autoDeleteJmsQueues) throws Exception
{
proxy.invokeOperation("addAddressSettings",
addressMatch,
@ -602,7 +604,9 @@ public class ActiveMQServerControlUsingCoreTest extends ActiveMQServerControlTes
addressFullMessagePolicy,
slowConsumerThreshold,
slowConsumerCheckPeriod,
slowConsumerPolicy);
slowConsumerPolicy,
autoCreateJmsQueues,
autoDeleteJmsQueues);
}
public void removeAddressSettings(String addressMatch) throws Exception

View File

@ -16,6 +16,7 @@
*/
package org.apache.activemq.tests.integration.persistence;
import org.junit.Ignore;
import org.junit.Test;
import java.io.StringReader;
@ -48,36 +49,39 @@ public class ExportFormatTest extends ServiceTestBase
// Case the format was changed, and the change was agreed, use _testCreateFormat to recreate this field
String bindingsFile = "#File,JournalFileImpl: (activemq-bindings-1.bindings id = 1, recordID = 1)\n" +
"operation@AddRecord,id@2,userRecordType@24,length@8,isUpdate@false,compactCount@0,data@AAAAAH____8=\n" +
"operation@AddRecord,id@2,userRecordType@21,length@17,isUpdate@false,compactCount@0,data@AAAABEEAMQAAAAAEQQAxAAA=\n" +
"operation@AddRecordTX,txID@2,id@3,userRecordType@21,length@18,isUpdate@false,compactCount@0,data@AAAABEEAMQAAAAAEQQAxAAAA\n" +
"operation@Commit,txID@2,numberOfRecords@1\n" +
"operation@AddRecord,id@20,userRecordType@24,length@8,isUpdate@false,compactCount@0,data@AAAAAAAAABQ=\n" +
"#File,JournalFileImpl: (activemq-bindings-2.bindings id = 2, recordID = 2)";
// Case the format was changed, and the change was agreed, use _testCreateFormat to recreate this field
String journalFile = "#File,JournalFileImpl: (activemq-data-1.amq id = 1, recordID = 1)\n" +
"operation@AddRecordTX,txID@0,id@4,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABAEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP40EAQAAAAEAAAAGawBlAHkABgAAAAA=\n" +
"operation@UpdateTX,txID@0,id@4,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecordTX,txID@0,id@5,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABQEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP5EEAQAAAAEAAAAGawBlAHkABgAAAAE=\n" +
"operation@UpdateTX,txID@0,id@5,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecordTX,txID@0,id@6,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABgEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP5EEAQAAAAEAAAAGawBlAHkABgAAAAI=\n" +
"operation@UpdateTX,txID@0,id@6,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecordTX,txID@0,id@7,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABwEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP5EEAQAAAAEAAAAGawBlAHkABgAAAAM=\n" +
"operation@UpdateTX,txID@0,id@7,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecordTX,txID@0,id@8,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAACAEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP5EEAQAAAAEAAAAGawBlAHkABgAAAAQ=\n" +
"operation@UpdateTX,txID@0,id@8,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecordTX,txID@0,id@5,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABQEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2CfYEAQAAAAEAAAAGawBlAHkABgAAAAA=\n" +
"operation@UpdateTX,txID@0,id@5,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecordTX,txID@0,id@6,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABgEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2CfoEAQAAAAEAAAAGawBlAHkABgAAAAE=\n" +
"operation@UpdateTX,txID@0,id@6,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecordTX,txID@0,id@7,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAABwEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2CfoEAQAAAAEAAAAGawBlAHkABgAAAAI=\n" +
"operation@UpdateTX,txID@0,id@7,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecordTX,txID@0,id@8,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAACAEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2CfoEAQAAAAEAAAAGawBlAHkABgAAAAM=\n" +
"operation@UpdateTX,txID@0,id@8,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecordTX,txID@0,id@9,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAACQEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2CfoEAQAAAAEAAAAGawBlAHkABgAAAAQ=\n" +
"operation@UpdateTX,txID@0,id@9,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@Commit,txID@0,numberOfRecords@10\n" +
"operation@AddRecord,id@12,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADAEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP6gEAQAAAAEAAAAGawBlAHkABgAAAAU=\n" +
"operation@Update,id@12,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecord,id@13,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADQEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP6oEAQAAAAEAAAAGawBlAHkABgAAAAY=\n" +
"operation@Update,id@13,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecord,id@14,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADgEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP6sEAQAAAAEAAAAGawBlAHkABgAAAAc=\n" +
"operation@Update,id@14,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecord,id@15,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADwEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP60EAQAAAAEAAAAGawBlAHkABgAAAAg=\n" +
"operation@Update,id@15,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecord,id@16,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAAEAEAAAAEQQAxAAAA_wAAAAAAAAAAAAABLLxYP64EAQAAAAEAAAAGawBlAHkABgAAAAk=\n" +
"operation@Update,id@16,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAI=\n" +
"operation@AddRecord,id@13,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADQEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2Cg0EAQAAAAEAAAAGawBlAHkABgAAAAU=\n" +
"operation@Update,id@13,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecord,id@14,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADgEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2Cg8EAQAAAAEAAAAGawBlAHkABgAAAAY=\n" +
"operation@Update,id@14,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecord,id@15,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAADwEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2ChMEAQAAAAEAAAAGawBlAHkABgAAAAc=\n" +
"operation@Update,id@15,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecord,id@16,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAAEAEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2ChcEAQAAAAEAAAAGawBlAHkABgAAAAg=\n" +
"operation@Update,id@16,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"operation@AddRecord,id@17,userRecordType@31,length@65,isUpdate@false,compactCount@0,data@AAAAEQAAAE4AAAAAAAAAEQEAAAAEQQAxAAAA_wAAAAAAAAAAAAABSuT2ChoEAQAAAAEAAAAGawBlAHkABgAAAAk=\n" +
"operation@Update,id@17,userRecordType@32,length@8,isUpdate@true,compactCount@0,data@AAAAAAAAAAM=\n" +
"#File,JournalFileImpl: (activemq-data-2.amq id = 2, recordID = 2)";
public void _testCreateFormat() throws Exception
@Test
@Ignore // use this to recreate the format above. Notice we can't change the record format between releases
public void testCreateFormat() throws Exception
{
ActiveMQServer server = createServer(true);
server.start();
@ -86,7 +90,7 @@ public class ExportFormatTest extends ServiceTestBase
ClientSessionFactory factory = createSessionFactory(locator);
ClientSession session = factory.createSession(false, false, false);
session.createQueue("A1", "A1");
session.createQueue("A1", "A1", true);
ClientProducer producer = session.createProducer("A1");
for (int i = 0; i < 5; i++)

View File

@ -0,0 +1,319 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tests.integration.server;
import java.util.Arrays;
import java.util.Collection;
import org.apache.activemq.api.core.Message;
import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.api.core.client.ActiveMQClient;
import org.apache.activemq.api.core.client.ClientConsumer;
import org.apache.activemq.api.core.client.ClientMessage;
import org.apache.activemq.api.core.client.ClientProducer;
import org.apache.activemq.api.core.client.ClientSession;
import org.apache.activemq.api.core.client.ClientSessionFactory;
import org.apache.activemq.core.postoffice.impl.LocalQueueBinding;
import org.apache.activemq.core.server.impl.ScaleDownHandler;
import org.apache.activemq.core.settings.impl.AddressSettings;
import org.apache.activemq.tests.integration.cluster.distribution.ClusterTestBase;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
/**
* On this test we will run ScaleDown directly as an unit-test in several cases,
* simulating what would happen during a real scale down.
*
* @author clebertsuconic
*/
@RunWith(value = Parameterized.class)
public class ScaleDownDirectTest extends ClusterTestBase
{
@Parameterized.Parameters(name = "isNetty={0}")
public static Collection getParameters()
{
return Arrays.asList(new Object[][]{
{false}, {true}
});
}
private final boolean isNetty;
public ScaleDownDirectTest(boolean isNetty)
{
this.isNetty = isNetty;
}
@Override
@Before
public void setUp() throws Exception
{
super.setUp();
setupLiveServer(0, isFileStorage(), isNetty, true);
setupLiveServer(1, isFileStorage(), isNetty, true);
startServers(0, 1);
setupSessionFactory(0, isNetty);
setupSessionFactory(1, isNetty);
}
@Override
@After
public void tearDown() throws Exception
{
super.tearDown();
}
@Test
public void testSendMixedSmallMessages() throws Exception
{
internalTest(100, 100);
}
@Test
public void testSendMixedLargelMessages() throws Exception
{
internalTest(2 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, 100);
}
protected void internalTest(int bufferSize, int numberOfMessages) throws Exception
{
ClientSessionFactory sf = sfs[0];
ClientSession session = sf.createSession(true, true);
session.createQueue("ad1", "queue1", true);
ClientProducer producer = session.createProducer("ad1");
byte[] buffer = new byte[bufferSize];
for (int i = 0; i < bufferSize; i++)
{
buffer[i] = getSamplebyte(i);
}
for (int i = 0; i < numberOfMessages; i++)
{
ClientMessage message = session.createMessage(true);
message.putIntProperty("i", i);
message.getBodyBuffer().writeBytes(buffer);
producer.send(message);
}
session.createQueue("ad1", "queue2", true);
for (int i = numberOfMessages; i < (numberOfMessages * 2); i++)
{
ClientMessage message = session.createMessage(true);
message.putIntProperty("i", i);
message.getBodyBuffer().writeBytes(buffer);
producer.send(message);
}
assertEquals(numberOfMessages * 2, performScaledown());
sfs[0].close();
session.close();
stopServers(0);
session = sfs[1].createSession(true, true);
ClientConsumer consumer1 = session.createConsumer("queue1");
session.start();
for (int i = 0; i < numberOfMessages * 2; i++)
{
ClientMessage message = consumer1.receive(5000);
assertNotNull(message);
assertEquals(i, message.getIntProperty("i").intValue());
// message.acknowledge();
checkBody(message, bufferSize);
}
ClientMessage messageCheckNull = consumer1.receiveImmediate();
assertNull(messageCheckNull);
ClientConsumer consumer2 = session.createConsumer("queue2");
for (int i = numberOfMessages; i < numberOfMessages * 2; i++)
{
ClientMessage message = consumer2.receive(5000);
assertNotNull(message);
assertEquals(i, message.getIntProperty("i").intValue());
// message.acknowledge();
checkBody(message, bufferSize);
}
messageCheckNull = consumer2.receiveImmediate();
System.out.println("Received " + messageCheckNull);
assertNull(messageCheckNull);
}
@Test
public void testPaging() throws Exception
{
final int CHUNK_SIZE = 50;
int messageCount = 0;
final String addressName = "testAddress";
final String queueName = "testQueue";
createQueue(0, addressName, queueName, null, true);
createQueue(1, addressName, queueName, null, true);
ClientSessionFactory sf = sfs[0];
ClientSession session = addClientSession(sf.createSession(false, false));
ClientProducer producer = addClientProducer(session.createProducer(addressName));
AddressSettings defaultSetting = new AddressSettings();
defaultSetting.setPageSizeBytes(10 * 1024);
defaultSetting.setMaxSizeBytes(20 * 1024);
servers[0].getAddressSettingsRepository().addMatch("#", defaultSetting);
while (!servers[0].getPagingManager().getPageStore(new SimpleString(addressName)).isPaging())
{
for (int i = 0; i < CHUNK_SIZE; i++)
{
Message message = session.createMessage(true);
message.getBodyBuffer().writeBytes(new byte[1024]);
// The only purpose of this count here is for eventually debug messages on print-data / print-pages
// message.putIntProperty("count", messageCount);
producer.send(message);
messageCount++;
}
session.commit();
}
assertEquals(messageCount, performScaledown());
servers[0].stop();
addConsumer(0, 1, queueName, null);
for (int i = 0; i < messageCount; i++)
{
ClientMessage message = consumers[0].getConsumer().receive(500);
Assert.assertNotNull(message);
// Assert.assertEquals(i, message.getIntProperty("count").intValue());
}
Assert.assertNull(consumers[0].getConsumer().receiveImmediate());
removeConsumer(0);
}
@Test
public void testBasicScaleDown() throws Exception
{
final int TEST_SIZE = 2;
final String addressName = "testAddress";
final String queueName1 = "testQueue1";
final String queueName2 = "testQueue2";
// create 2 queues on each node mapped to the same address
createQueue(0, addressName, queueName1, null, true);
createQueue(0, addressName, queueName2, null, true);
createQueue(1, addressName, queueName1, null, true);
createQueue(1, addressName, queueName2, null, true);
// send messages to node 0
send(0, addressName, TEST_SIZE, true, null);
// consume a message from queue 2
addConsumer(1, 0, queueName2, null, false);
ClientMessage clientMessage = consumers[1].getConsumer().receive(250);
Assert.assertNotNull(clientMessage);
clientMessage.acknowledge();
consumers[1].getSession().commit();
removeConsumer(1);
// at this point on node 0 there should be 2 messages in testQueue1 and 1 message in testQueue2
Assert.assertEquals(TEST_SIZE, getMessageCount(((LocalQueueBinding) servers[0].getPostOffice().getBinding(new SimpleString(queueName1))).getQueue()));
Assert.assertEquals(TEST_SIZE - 1, getMessageCount(((LocalQueueBinding) servers[0].getPostOffice().getBinding(new SimpleString(queueName2))).getQueue()));
assertEquals(TEST_SIZE, performScaledown());
// trigger scaleDown from node 0 to node 1
servers[0].stop();
// get the 2 messages from queue 1
addConsumer(0, 1, queueName1, null);
clientMessage = consumers[0].getConsumer().receive(250);
Assert.assertNotNull(clientMessage);
clientMessage.acknowledge();
clientMessage = consumers[0].getConsumer().receive(250);
Assert.assertNotNull(clientMessage);
clientMessage.acknowledge();
// ensure there are no more messages on queue 1
clientMessage = consumers[0].getConsumer().receive(250);
Assert.assertNull(clientMessage);
removeConsumer(0);
// get the 1 message from queue 2
addConsumer(0, 1, queueName2, null);
clientMessage = consumers[0].getConsumer().receive(250);
Assert.assertNotNull(clientMessage);
clientMessage.acknowledge();
// ensure there are no more messages on queue 1
clientMessage = consumers[0].getConsumer().receive(250);
Assert.assertNull(clientMessage);
removeConsumer(0);
}
private void checkBody(ClientMessage message, int bufferSize)
{
assertEquals(bufferSize, message.getBodySize());
byte[] body = new byte[message.getBodySize()];
message.getBodyBuffer().readBytes(body);
for (int bpos = 0; bpos < bufferSize; bpos++)
{
if (getSamplebyte(bpos) != body[bpos])
{
fail("body comparison failure at " + message);
}
}
}
private long performScaledown() throws Exception
{
ScaleDownHandler handler = new ScaleDownHandler(servers[0].getPagingManager(), servers[0].getPostOffice(),
servers[0].getNodeManager(),
servers[0].getClusterManager().getClusterController(),
servers[0].getStorageManager());
return handler.scaleDownMessages(sfs[1], servers[1].getNodeID());
}
}

View File

@ -30,8 +30,6 @@ import org.apache.activemq.api.core.client.ClientSessionFactory;
import org.apache.activemq.api.core.client.ActiveMQClient;
import org.apache.activemq.core.config.ScaleDownConfiguration;
import org.apache.activemq.core.config.ha.LiveOnlyPolicyConfiguration;
import org.apache.activemq.core.persistence.impl.journal.JournalStorageManager;
import org.apache.activemq.core.persistence.impl.journal.LargeServerMessageImpl;
import org.apache.activemq.core.postoffice.Binding;
import org.apache.activemq.core.postoffice.impl.LocalQueueBinding;
import org.apache.activemq.core.settings.impl.AddressSettings;
@ -119,13 +117,13 @@ public class ScaleDownTest extends ClusterTestBase
final String queueName2 = "testQueue2";
// create 2 queues on each node mapped to the same address
createQueue(0, addressName, queueName1, null, false);
createQueue(0, addressName, queueName2, null, false);
createQueue(1, addressName, queueName1, null, false);
createQueue(1, addressName, queueName2, null, false);
createQueue(0, addressName, queueName1, null, true);
createQueue(0, addressName, queueName2, null, true);
createQueue(1, addressName, queueName1, null, true);
createQueue(1, addressName, queueName2, null, true);
// send messages to node 0
send(0, addressName, TEST_SIZE, false, null);
send(0, addressName, TEST_SIZE, true, null);
// consume a message from queue 2
addConsumer(1, 0, queueName2, null, false);
@ -375,32 +373,28 @@ public class ScaleDownTest extends ClusterTestBase
final String addressName = "testAddress";
final String queueName = "testQueue";
createQueue(0, addressName, queueName, null, false);
createQueue(1, addressName, queueName, null, false);
createQueue(0, addressName, queueName, null, true);
createQueue(1, addressName, queueName, null, true);
ClientSessionFactory sf = sfs[0];
ClientSession session = addClientSession(sf.createSession(false, false));
ClientProducer producer = addClientProducer(session.createProducer(addressName));
LargeServerMessageImpl fileMessage = new LargeServerMessageImpl((JournalStorageManager) servers[0].getStorageManager());
fileMessage.setMessageID(1005);
fileMessage.setDurable(true);
for (int i = 0; i < 2 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
byte[] buffer = new byte[2 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE];
for (int i = 0; i < buffer.length; i++)
{
fileMessage.addBytes(new byte[]{UnitTestCase.getSamplebyte(i)});
buffer[i] = getSamplebyte(i);
}
fileMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, 2 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE);
fileMessage.releaseResources();
producer.send(fileMessage);
fileMessage.deleteFile();
for (int nmsg = 0; nmsg < 10; nmsg++)
{
ClientMessage message = session.createMessage(true);
message.getBodyBuffer().writeBytes(buffer);
producer.send(message);
session.commit();
}
servers[0].stop();
@ -409,6 +403,8 @@ public class ScaleDownTest extends ClusterTestBase
ClientConsumer consumer = addClientConsumer(session.createConsumer(queueName));
session.start();
for (int nmsg = 0; nmsg < 10; nmsg++)
{
ClientMessage msg = consumer.receive(250);
Assert.assertNotNull(msg);
@ -417,12 +413,14 @@ public class ScaleDownTest extends ClusterTestBase
for (int i = 0; i < 2 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
{
Assert.assertEquals(UnitTestCase.getSamplebyte(i), msg.getBodyBuffer().readByte());
byte byteRead = msg.getBodyBuffer().readByte();
Assert.assertEquals(msg + " Is different", UnitTestCase.getSamplebyte(i), byteRead);
}
msg.acknowledge();
session.commit();
}
}
@Test
public void testPaging() throws Exception

View File

@ -34,6 +34,7 @@ import javax.jms.XAConnection;
import javax.jms.XASession;
import org.apache.activemq.api.jms.JMSFactoryType;
import org.apache.activemq.core.settings.impl.AddressSettings;
import org.apache.activemq.jms.tests.util.ProxyAssertSupport;
import org.junit.Test;
@ -113,6 +114,10 @@ public class SessionTest extends ActiveMQServerTestCase
@Test
public void testCreateNonExistentQueue() throws Exception
{
AddressSettings addressSettings = new AddressSettings();
addressSettings.setAutoCreateJmsQueues(false);
getJmsServer().getAddressSettingsRepository().addMatch("#", addressSettings);
Connection conn = getConnectionFactory().createConnection();
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
@ -147,6 +152,10 @@ public class SessionTest extends ActiveMQServerTestCase
@Test
public void testCreateQueueWhileTopicWithSameNameExists() throws Exception
{
AddressSettings addressSettings = new AddressSettings();
addressSettings.setAutoCreateJmsQueues(false);
getJmsServer().getAddressSettingsRepository().addMatch("#", addressSettings);
Connection conn = getConnectionFactory().createConnection();
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
try

View File

@ -81,6 +81,7 @@ public class QueueImplTest extends UnitTestCase
null,
false,
true,
false,
scheduledExecutor,
null,
null,
@ -158,6 +159,7 @@ public class QueueImplTest extends UnitTestCase
null,
false,
true,
false,
scheduledExecutor,
null,
null,
@ -273,6 +275,7 @@ public class QueueImplTest extends UnitTestCase
null,
false,
true,
false,
scheduledExecutor,
null,
null,

View File

@ -25,7 +25,6 @@ import org.apache.activemq.api.core.SimpleString;
import org.apache.activemq.core.filter.Filter;
import org.apache.activemq.core.paging.cursor.PageSubscription;
import org.apache.activemq.core.server.Consumer;
import org.apache.activemq.core.server.ActiveMQServer;
import org.apache.activemq.core.server.MessageReference;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.core.server.RoutingContext;
@ -60,7 +59,7 @@ public class FakeQueue implements Queue
}
@Override
public void setConsumersRefCount(ActiveMQServer server)
public void setConsumersRefCount(ReferenceCounter referenceCounter)
{
}
@ -362,9 +361,9 @@ public class FakeQueue implements Queue
}
@Override
public List<MessageReference> cancelScheduledMessages()
public void deliverScheduledMessages()
{
return null;
}
@Override
@ -427,6 +426,12 @@ public class FakeQueue implements Queue
return false;
}
@Override
public boolean isAutoCreated()
{
return false;
}
@Override
public LinkedListIterator<MessageReference> iterator()
{

View File

@ -94,17 +94,7 @@ public class QueueImplTest extends UnitTestCase
{
final SimpleString name = new SimpleString("oobblle");
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
name,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getNamedQueue(name);
Assert.assertEquals(name, queue.getName());
}
@ -112,31 +102,11 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testDurable()
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
false,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getNonDurableQueue();
Assert.assertFalse(queue.isDurable());
queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
true,
false,
scheduledExecutor,
null,
null,
null,
executor);
queue = getDurableQueue();
Assert.assertTrue(queue.isDurable());
}
@ -150,17 +120,7 @@ public class QueueImplTest extends UnitTestCase
Consumer cons3 = new FakeConsumer();
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
Assert.assertEquals(0, queue.getConsumerCount());
@ -202,17 +162,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testGetFilter()
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
Assert.assertNull(queue.getFilter());
@ -229,17 +179,7 @@ public class QueueImplTest extends UnitTestCase
}
};
queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
filter,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
queue = getFilteredQueue(filter);
Assert.assertEquals(filter, queue.getFilter());
@ -248,17 +188,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testSimpleadd()
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -278,17 +208,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testRate() throws InterruptedException
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -309,17 +229,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testSimpleNonDirectDelivery() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -358,17 +268,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testBusyConsumer() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
FakeConsumer consumer = new FakeConsumer();
@ -413,17 +313,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testBusyConsumerThenAddMoreMessages() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
FakeConsumer consumer = new FakeConsumer();
@ -491,17 +381,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testaddHeadadd() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -556,17 +436,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testChangeConsumersAndDeliver() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
new FakePostOffice(),
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -730,17 +600,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testRoundRobinWithQueueing() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -793,17 +653,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testWithPriorities() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
@ -856,17 +706,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testConsumerWithFilterAddAndRemove()
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
Filter filter = new FakeFilter("fruit", "orange");
@ -876,17 +716,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testIterator()
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 20;
@ -925,17 +755,7 @@ public class QueueImplTest extends UnitTestCase
public void testConsumeWithFiltersAddAndRemoveConsumer() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
new FakePostOffice(),
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
Filter filter = new FakeFilter("fruit", "orange");
@ -1009,17 +829,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testBusyConsumerWithFilterFirstCallBusy() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
FakeConsumer consumer = new FakeConsumer(FilterImpl.createFilter("color = 'green'"));
@ -1061,17 +871,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testBusyConsumerWithFilterThenAddMoreMessages() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
FakeConsumer consumer = new FakeConsumer(FilterImpl.createFilter("color = 'green'"));
@ -1146,17 +946,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testConsumerWithFilterThenAddMoreMessages() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
final int numMessages = 10;
List<MessageReference> refs = new ArrayList<MessageReference>();
@ -1220,17 +1010,7 @@ public class QueueImplTest extends UnitTestCase
private void testConsumerWithFilters(final boolean direct) throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
new FakePostOffice(),
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
Filter filter = new FakeFilter("fruit", "orange");
@ -1323,17 +1103,7 @@ public class QueueImplTest extends UnitTestCase
public void testMessageOrder() throws Exception
{
FakeConsumer consumer = new FakeConsumer();
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
MessageReference messageReference = generateReference(queue, 1);
MessageReference messageReference2 = generateReference(queue, 2);
MessageReference messageReference3 = generateReference(queue, 3);
@ -1354,17 +1124,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testMessagesAdded() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
MessageReference messageReference = generateReference(queue, 1);
MessageReference messageReference2 = generateReference(queue, 2);
MessageReference messageReference3 = generateReference(queue, 3);
@ -1377,17 +1137,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testGetReference() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
MessageReference messageReference = generateReference(queue, 1);
MessageReference messageReference2 = generateReference(queue, 2);
MessageReference messageReference3 = generateReference(queue, 3);
@ -1401,17 +1151,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testGetNonExistentReference() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
MessageReference messageReference = generateReference(queue, 1);
MessageReference messageReference2 = generateReference(queue, 2);
MessageReference messageReference3 = generateReference(queue, 3);
@ -1430,17 +1170,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testPauseAndResumeWithAsync() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
// pauses the queue
queue.pause();
@ -1498,17 +1228,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testPauseAndResumeWithDirect() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
// Now add a consumer
FakeConsumer consumer = new FakeConsumer();
@ -1553,17 +1273,7 @@ public class QueueImplTest extends UnitTestCase
@Test
public void testResetMessagesAdded() throws Exception
{
QueueImpl queue = new QueueImpl(1,
QueueImplTest.address1,
QueueImplTest.queue1,
null,
false,
true,
scheduledExecutor,
null,
null,
null,
executor);
QueueImpl queue = getTemporaryQueue();
MessageReference messageReference = generateReference(queue, 1);
MessageReference messageReference2 = generateReference(queue, 2);
queue.addTail(messageReference);
@ -1668,4 +1378,45 @@ public class QueueImplTest extends UnitTestCase
server.stop();
}
}
private QueueImpl getNonDurableQueue()
{
return getQueue(QueueImplTest.queue1, false, false, null);
}
private QueueImpl getDurableQueue()
{
return getQueue(QueueImplTest.queue1, true, false, null);
}
private QueueImpl getNamedQueue(SimpleString name)
{
return getQueue(name, false, true, null);
}
private QueueImpl getFilteredQueue(Filter filter)
{
return getQueue(QueueImplTest.queue1, false, true, filter);
}
private QueueImpl getTemporaryQueue()
{
return getQueue(QueueImplTest.queue1, false, true, null);
}
private QueueImpl getQueue(SimpleString name, boolean durable, boolean temporary, Filter filter)
{
return new QueueImpl(1,
QueueImplTest.address1,
name,
filter,
durable,
temporary,
false,
scheduledExecutor,
new FakePostOffice(),
null,
null,
executor);
}
}

View File

@ -17,6 +17,7 @@
package org.apache.activemq.tests.unit.core.server.impl.fakes;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.api.core.Pair;
import org.apache.activemq.api.core.SimpleString;
@ -43,6 +44,12 @@ public class FakePostOffice implements PostOffice
return false;
}
@Override
public Set<SimpleString> getAddresses()
{
return null;
}
@Override
public void start() throws Exception
{

Some files were not shown because too many files have changed in this diff Show More