Merge branch #62
This commit is contained in:
commit
260f579c18
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,4 +43,6 @@ public interface QueueBindingInfo
|
|||
|
||||
SimpleString getFilterString();
|
||||
|
||||
boolean isAutoCreated();
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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 -
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 +
|
||||
"]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
5
pom.xml
5
pom.xml
|
@ -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>
|
||||
|
|
|
@ -77,6 +77,7 @@ public class QueueTest extends UnitTestCase
|
|||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
|
||||
FakeConsumer consumer = new FakeConsumer();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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")));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue