INT-3642: Improve MessageGroupStore Removal
JIRA: https://jira.spring.io/browse/INT-3642 Currently, `removeMessageFromGroup` rebuilds the group on every removal. In every case where this method is used in the framework, the result is not used. Add `removeMessagesFromGroup` that removes a collection of messages and returns no result. INT-3642: Polishing - PR Comments INT-3642: Polishing and Fix Group Metadata Size
This commit is contained in:
committed by
Artem Bilan
parent
0065ed8c49
commit
f3d525a5e8
@@ -49,6 +49,7 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.integration.store.AbstractBatchingMessageGroupStore;
|
||||
import org.springframework.integration.store.BasicMessageGroupStore;
|
||||
import org.springframework.integration.support.DefaultMessageBuilderFactory;
|
||||
import org.springframework.integration.support.MessageBuilderFactory;
|
||||
@@ -65,8 +66,8 @@ import org.springframework.util.Assert;
|
||||
* @since 4.0
|
||||
*/
|
||||
|
||||
public abstract class AbstractConfigurableMongoDbMessageStore implements BasicMessageGroupStore, InitializingBean,
|
||||
ApplicationContextAware {
|
||||
public abstract class AbstractConfigurableMongoDbMessageStore extends AbstractBatchingMessageGroupStore
|
||||
implements BasicMessageGroupStore, InitializingBean, ApplicationContextAware {
|
||||
|
||||
public final static String SEQUENCE_NAME = "messagesSequence";
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.mongodb.store;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -48,6 +49,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Amol Nayak
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConfigurableMongoDbMessageStore extends AbstractConfigurableMongoDbMessageStore
|
||||
@@ -205,10 +207,39 @@ public class ConfigurableMongoDbMessageStore extends AbstractConfigurableMongoDb
|
||||
|
||||
Query query = groupIdQuery(groupId)
|
||||
.addCriteria(Criteria.where(MessageDocumentFields.MESSAGE_ID).is(messageToRemove.getHeaders().getId()));
|
||||
mongoTemplate.remove(query, collectionName);
|
||||
this.mongoTemplate.remove(query, this.collectionName);
|
||||
updateGroup(groupId, lastModifiedUpdate());
|
||||
return getMessageGroup(groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessagesFromGroup(Object groupId, Collection<Message<?>> messages) {
|
||||
Assert.notNull(groupId, "'groupId' must not be null");
|
||||
Assert.notNull(messages, "'messageToRemove' must not be null");
|
||||
|
||||
Collection<UUID> ids = new ArrayList<UUID>();
|
||||
for (Message<?> messageToRemove : messages) {
|
||||
ids.add(messageToRemove.getHeaders().getId());
|
||||
if (ids.size() >= getRemoveBatchSize()) {
|
||||
removeMessages(groupId, ids);
|
||||
ids.clear();
|
||||
}
|
||||
}
|
||||
if (ids.size() > 0) {
|
||||
removeMessages(groupId, ids);
|
||||
}
|
||||
updateGroup(groupId, lastModifiedUpdate());
|
||||
}
|
||||
|
||||
private void removeMessages(Object groupId, Collection<UUID> ids) {
|
||||
Query query = groupIdQuery(groupId)
|
||||
.addCriteria(Criteria.where(MessageDocumentFields.MESSAGE_ID).in(ids.toArray()));
|
||||
this.mongoTemplate.remove(query, this.collectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessagesFromGroup(Object groupId, Message<?>... messages) {
|
||||
removeMessagesFromGroup(groupId, Arrays.asList(messages));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.mongodb.store;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -76,6 +77,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BulkWriteOperation;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
@@ -313,6 +315,35 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore
|
||||
return getMessageGroup(groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessagesFromGroup(Object groupId, Collection<Message<?>> messages) {
|
||||
Assert.notNull(groupId, "'groupId' must not be null");
|
||||
Assert.notNull(messages, "'messageToRemove' must not be null");
|
||||
|
||||
Collection<UUID> ids = new ArrayList<UUID>();
|
||||
for (Message<?> messageToRemove : messages) {
|
||||
ids.add(messageToRemove.getHeaders().getId());
|
||||
if (ids.size() >= getRemoveBatchSize()) {
|
||||
bulkRemove(groupId, ids);
|
||||
ids.clear();
|
||||
}
|
||||
}
|
||||
if (ids.size() > 0) {
|
||||
bulkRemove(groupId, ids);
|
||||
}
|
||||
updateGroup(groupId, lastModifiedUpdate());
|
||||
}
|
||||
|
||||
private void bulkRemove(Object groupId, Collection<UUID> ids) {
|
||||
BulkWriteOperation bulkOp = this.template.getCollection(this.collectionName)
|
||||
.initializeOrderedBulkOperation();
|
||||
for (UUID id : ids) {
|
||||
bulkOp.find(whereMessageIdIsAndGroupIdIs(id, groupId).getQueryObject())
|
||||
.remove();
|
||||
}
|
||||
bulkOp.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessageGroup(Object groupId) {
|
||||
this.template.remove(whereGroupIdIs(groupId), this.collectionName);
|
||||
@@ -400,7 +431,6 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore
|
||||
return new Query(Criteria.where("headers.id._value").is(id.toString()).and(GROUP_ID_KEY).is(groupId));
|
||||
}
|
||||
|
||||
|
||||
private static Query whereGroupIdOrder(Object groupId) {
|
||||
return whereGroupIdIs(groupId).with(new Sort(Sort.Direction.DESC, GROUP_UPDATE_TIMESTAMP_KEY, SEQUENCE));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,14 +15,19 @@
|
||||
*/
|
||||
package org.springframework.integration.mongodb.store;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -32,6 +37,7 @@ import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.history.MessageHistory;
|
||||
import org.springframework.integration.mongodb.rules.MongoDbAvailable;
|
||||
import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
|
||||
import org.springframework.integration.store.AbstractBatchingMessageGroupStore;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.integration.store.MessageStore;
|
||||
@@ -41,6 +47,8 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
@@ -394,6 +402,26 @@ public abstract class AbstractMongoDbMessageGroupStoreTests extends MongoDbAvail
|
||||
assertEquals(2, counter);
|
||||
}
|
||||
|
||||
@Test
|
||||
@MongoDbAvailable
|
||||
public void testAddAndRemoveMessagesFromMessageGroup() throws Exception {
|
||||
MessageGroupStore messageStore = (MessageGroupStore) this.getMessageStore();
|
||||
String groupId = "X";
|
||||
messageStore.removeMessageGroup("X");
|
||||
((AbstractBatchingMessageGroupStore) messageStore).setRemoveBatchSize(10);
|
||||
List<Message<?>> messages = new ArrayList<Message<?>>();
|
||||
for (int i = 0; i < 25; i++) {
|
||||
Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
|
||||
messageStore.addMessageToGroup(groupId, message);
|
||||
messages.add(message);
|
||||
}
|
||||
MessageGroup group = messageStore.getMessageGroup(groupId);
|
||||
assertEquals(25, group.size());
|
||||
messageStore.removeMessagesFromGroup(groupId, messages);
|
||||
group = messageStore.getMessageGroup(groupId);
|
||||
assertEquals(0, group.size());
|
||||
}
|
||||
|
||||
// @Test
|
||||
// @MongoDbAvailable
|
||||
// public void testConcurrentModifications() throws Exception{
|
||||
@@ -461,6 +489,7 @@ public abstract class AbstractMongoDbMessageGroupStoreTests extends MongoDbAvail
|
||||
Message<?> m3 = MessageBuilder.withPayload("3").setSequenceNumber(3).setSequenceSize(3).setCorrelationId(1).build();
|
||||
input.send(m3);
|
||||
assertNotNull(output.receive(2000));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package org.springframework.integration.mongodb.store;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoClient;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -38,6 +38,9 @@ import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* @author Amol Nayak
|
||||
* @author Artem Bilan
|
||||
@@ -45,9 +48,6 @@ import org.springframework.messaging.Message;
|
||||
*/
|
||||
public class ConfigurableMongoDbMessageGroupStoreTests extends AbstractMongoDbMessageGroupStoreTests {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.integration.mongodb.store.AbstractMongoDbMessageGroupStoreTests#getMessageGroupStore()
|
||||
*/
|
||||
@Override
|
||||
protected ConfigurableMongoDbMessageStore getMessageGroupStore() throws Exception {
|
||||
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new MongoClient(), "test");
|
||||
@@ -59,9 +59,6 @@ public class ConfigurableMongoDbMessageGroupStoreTests extends AbstractMongoDbMe
|
||||
return mongoDbMessageStore;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.integration.mongodb.store.AbstractMongoDbMessageGroupStoreTests#getMessageStore()
|
||||
*/
|
||||
@Override
|
||||
protected MessageStore getMessageStore() throws Exception {
|
||||
return this.getMessageGroupStore();
|
||||
|
||||
Reference in New Issue
Block a user