/*
* 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.artemis.tests.unit.core.postoffice.impl;
import javax.transaction.xa.Xid;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.filter.Filter;
import org.apache.activemq.artemis.core.message.impl.CoreMessage;
import org.apache.activemq.artemis.core.postoffice.Binding;
import org.apache.activemq.artemis.core.postoffice.BindingType;
import org.apache.activemq.artemis.core.postoffice.Bindings;
import org.apache.activemq.artemis.core.postoffice.impl.BindingsImpl;
import org.apache.activemq.artemis.core.server.Bindable;
import org.apache.activemq.artemis.core.server.Queue;
import org.apache.activemq.artemis.core.server.RoutingContext;
import org.apache.activemq.artemis.core.server.impl.RefsOperation;
import org.apache.activemq.artemis.core.server.impl.RoutingContextImpl;
import org.apache.activemq.artemis.core.transaction.Transaction;
import org.apache.activemq.artemis.core.transaction.TransactionOperation;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Test;
public class BindingsImplTest extends ActiveMQTestBase {
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
@Test
public void testRemoveWhileRouting() throws Exception {
// It would require many iterations before getting a failure
for (int i = 0; i < 500; i++) {
internalTest(true);
}
}
@Test
public void testRemoveWhileRedistributing() throws Exception {
// It would require many iterations before getting a failure
for (int i = 0; i < 500; i++) {
internalTest(false);
}
}
private void internalTest(final boolean route) throws Exception {
final FakeBinding fake = new FakeBinding(new SimpleString("a"));
final Bindings bind = new BindingsImpl(null, null, null);
bind.addBinding(fake);
bind.addBinding(new FakeBinding(new SimpleString("a")));
bind.addBinding(new FakeBinding(new SimpleString("a")));
Thread t = new Thread() {
@Override
public void run() {
try {
bind.removeBinding(fake);
} catch (Exception e) {
e.printStackTrace();
}
}
};
Queue queue = new FakeQueue(new SimpleString("a"));
t.start();
for (int i = 0; i < 100; i++) {
if (route) {
bind.route(new CoreMessage(i, 100), new RoutingContextImpl(new FakeTransaction()));
} else {
bind.redistribute(new CoreMessage(i, 100), queue, new RoutingContextImpl(new FakeTransaction()));
}
}
}
private final class FakeTransaction implements Transaction {
@Override
public Object getProtocolData() {
return null;
}
@Override
public void setProtocolData(Object data) {
}
@Override
public void afterStore(TransactionOperation sync) {
}
@Override
public void addOperation(final TransactionOperation sync) {
}
@Override
public boolean isEffective() {
return false;
}
@Override
public boolean hasTimedOut(long currentTime, int defaultTimeout) {
return false;
}
@Override
public void commit() throws Exception {
}
@Override
public void commit(final boolean onePhase) throws Exception {
}
@Override
public long getCreateTime() {
return 0;
}
@Override
public long getID() {
return 0;
}
@Override
public Object getProperty(final int index) {
return null;
}
@Override
public boolean isContainsPersistent() {
return false;
}
@Override
public State getState() {
return null;
}
@Override
public Xid getXid() {
return null;
}
@Override
public void markAsRollbackOnly(final ActiveMQException exception) {
}
@Override
public void prepare() throws Exception {
}
@Override
public void putProperty(final int index, final Object property) {
}
public void removeOperation(final TransactionOperation sync) {
}
@Override
public void resume() {
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.transaction.Transaction#rollback()
*/
@Override
public void rollback() throws Exception {
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.transaction.Transaction#setState(org.apache.activemq.artemis.core.transaction.Transaction.State)
*/
@Override
public void setState(final State state) {
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.transaction.Transaction#suspend()
*/
@Override
public void suspend() {
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.transaction.Transaction#getDistinctQueues()
*/
public Set<Queue> getDistinctQueues() {
return Collections.emptySet();
}
@Override
public void setContainsPersistent() {
}
@Override
public void setTimeout(int timeout) {
}
@Override
public List<TransactionOperation> getAllOperations() {
return null;
}
public void setWaitBeforeCommit(boolean waitBeforeCommit) {
}
@Override
public RefsOperation createRefsOperation(Queue queue) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean hasTimedOut() {
return false;
}
}
private final class FakeFilter implements Filter {
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.filter.Filter#getFilterString()
*/
@Override
public SimpleString getFilterString() {
return null;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.filter.Filter#match(org.apache.activemq.artemis.core.server.ServerMessage)
*/
@Override
public boolean match(final Message message) {
return false;
}
}
private final class FakeBinding implements Binding {
@Override
public void close() throws Exception {
}
@Override
public void unproposed(SimpleString groupID) {
}
final SimpleString name;
FakeBinding(final SimpleString name) {
this.name = name;
}
@Override
public SimpleString getAddress() {
return null;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getBindable()
*/
@Override
public Bindable getBindable() {
return null;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getClusterName()
*/
@Override
public SimpleString getClusterName() {
return null;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getDistance()
*/
@Override
public int getDistance() {
return 0;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getFilter()
*/
@Override
public Filter getFilter() {
return new FakeFilter();
}
@Override
public long getID() {
return 0;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getRoutingName()
*/
@Override
public SimpleString getRoutingName() {
return name;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getType()
*/
@Override
public BindingType getType() {
return null;
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#getUniqueName()
*/
@Override
public SimpleString getUniqueName() {
return null;
}
@Override
public boolean isExclusive() {
return false;
}
@Override
public boolean isHighAcceptPriority(final Message message) {
return false;
}
@Override
public void route(final Message message, final RoutingContext context) throws Exception {
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.postoffice.Binding#toManagementString()
*/
@Override
public String toManagementString() {
return null;
}
@Override
public boolean isConnected() {
return true;
}
@Override
public void routeWithAck(Message message, RoutingContext context) {
}
}
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}