AMQ-7151 - Remove dependency on Guava from activemq-broker

Guava is supposed to only be used for the leveldb store and as a test
    dependency elsewhere but there is one spot it is used in activemq-broker for
    filtering collections. With Java 8 this can be easily rewritten to avoid the use of Guava.

    This commit is based on the patch submitted by Filip Hrisafov
This commit is contained in:
Christopher L. Shannon (cshannon) 2019-02-18 07:49:47 -05:00
parent 1cf13c4742
commit 7fdad3a73d
3 changed files with 68 additions and 39 deletions

View File

@ -83,11 +83,6 @@
<artifactId>slf4j-log4j12</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>

View File

@ -16,25 +16,28 @@
*/
package org.apache.activemq.broker.jmx;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import static org.apache.activemq.util.IntrospectionSupport.findGetterMethod;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.management.ObjectName;
import org.apache.activemq.advisory.AdvisorySupport;
import org.apache.activemq.command.ActiveMQTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.management.ObjectName;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import static org.apache.activemq.util.IntrospectionSupport.*;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Defines a query API for destinations MBeans
@ -126,8 +129,12 @@ public class DestinationsViewFilter implements Serializable {
* @throws IOException
*/
String filter(int page, int pageSize) throws IOException {
ObjectMapper mapper = new ObjectMapper();
destinations = Maps.filterValues(destinations, getPredicate());
final ObjectMapper mapper = new ObjectMapper();
final Predicate<DestinationView> predicate = getPredicate();
final Map<ObjectName, DestinationView> filteredDestinations = new HashMap<>(destinations);
destinations = filteredDestinations.entrySet().stream().filter(d -> predicate.test(d.getValue())).collect(
Collectors.toMap(d -> d.getKey(), d -> d.getValue()));
Map<ObjectName, DestinationView> pagedDestinations = getPagedDestinations(page, pageSize);
Map<String, Object> result = new HashMap<String, Object>();
result.put("data", pagedDestinations);
@ -138,24 +145,19 @@ public class DestinationsViewFilter implements Serializable {
}
Map<ObjectName, DestinationView> getPagedDestinations(int page, int pageSize) {
ImmutableMap.Builder<ObjectName, DestinationView> builder = ImmutableMap.builder();
int start = (page - 1) * pageSize;
int end = Math.min(page * pageSize, destinations.size());
int i = 0;
for (Map.Entry<ObjectName, DestinationView> entry :
getOrdering().sortedCopy(destinations.entrySet())) {
if (i >= start && i < end) {
builder.put(entry.getKey(), entry.getValue());
}
i++;
}
return builder.build();
final List<Map.Entry<ObjectName, DestinationView>> sortedCopy = new ArrayList<>(destinations.entrySet());
sortedCopy.sort(getComparator());
return sortedCopy.subList(start, end).stream().collect(
Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));
}
Predicate<DestinationView> getPredicate() {
return new Predicate<DestinationView>() {
@Override
public boolean apply(DestinationView input) {
public boolean test(DestinationView input) {
boolean match = true;
if (getName() != null && !getName().isEmpty()) {
match = input.getName().contains(getName());
@ -181,11 +183,12 @@ public class DestinationsViewFilter implements Serializable {
};
}
Ordering<Map.Entry<ObjectName, DestinationView>> getOrdering() {
return new Ordering<Map.Entry<ObjectName, DestinationView>>() {
Comparator<Map.Entry<ObjectName, DestinationView>> getComparator() {
return new Comparator<Map.Entry<ObjectName, DestinationView>>() {
Method getter = findGetterMethod(DestinationView.class, getSortColumn());
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public int compare(Map.Entry<ObjectName, DestinationView> left, Map.Entry<ObjectName, DestinationView> right) {
try {

View File

@ -16,19 +16,30 @@
*/
package org.apache.activemq.broker.view;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Map;
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerRegistry;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.DestinationsViewFilter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import com.fasterxml.jackson.databind.ObjectMapper;
public class BrokerDestinationViewTest {
@ -42,8 +53,7 @@ public class BrokerDestinationViewTest {
protected Queue queue;
protected int messageCount = 10000;
protected int timeOutInSeconds = 10;
protected String queueName = "testQueue";
@Before
public void setUp() throws Exception {
@ -55,7 +65,7 @@ public class BrokerDestinationViewTest {
producerConnection = factory.createConnection();
producerConnection.start();
producerSession = producerConnection.createSession(false,Session.AUTO_ACKNOWLEDGE);
queue = producerSession.createQueue(getClass().getName());
queue = producerSession.createQueue(queueName);
producer = producerSession.createProducer(queue);
}
@ -76,9 +86,30 @@ public class BrokerDestinationViewTest {
producer.send(message);
}
MessageBrokerView messageBrokerView = MessageBrokerViewRegistry.getInstance().lookup("");
BrokerDestinationView destinationView = messageBrokerView.getQueueDestinationView(getClass().getName());
BrokerDestinationView destinationView = messageBrokerView.getQueueDestinationView(queueName);
assertEquals(destinationView.getQueueSize(),messageCount);
final DestinationsViewFilter filter = new DestinationsViewFilter();
filter.setName(queueName);
filter.setFilter("nonEmpty");
final ObjectMapper mapper = new ObjectMapper();
final BrokerViewMBean brokerView = getBrokerView();
String output = brokerView.queryQueues(mapper.writeValueAsString(filter), 1, 10);
Map<?,?> queryResults = mapper.readValue(output, Map.class);
final Integer count = (Integer) queryResults.get("count");
final Map<?,?> data = (Map<?, ?>) queryResults.get("data");
assertEquals((Integer)1, count);
assertEquals(1, data.size());
}
private BrokerViewMBean getBrokerView() throws MalformedObjectNameException {
ObjectName brokerName = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");
BrokerViewMBean view = (BrokerViewMBean) brokerService.getManagementContext().newProxyInstance(brokerName, BrokerViewMBean.class, true);
assertNotNull(view);
return view;
}
}