INT-1527 MetadataStore refactoring

This commit is contained in:
Mark Fisher
2010-10-26 18:39:52 -04:00
parent ce0e9f4e0a
commit 7412bc239c
14 changed files with 439 additions and 362 deletions

View File

@@ -18,18 +18,18 @@ package org.springframework.integration.twitter.inbound;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ScheduledFuture;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.integration.Message;
import org.springframework.integration.context.metadata.FileBasedPropertiesStore;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.context.metadata.MetadataStore;
import org.springframework.integration.context.metadata.SimpleMetadataStore;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.history.HistoryWritingMessagePostProcessor;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.twitter.oauth.OAuthConfiguration;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import twitter4j.DirectMessage;
import twitter4j.Status;
@@ -45,6 +45,7 @@ import twitter4j.Twitter;
*
* @author Josh Long
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.0
*/
public abstract class AbstractInboundTwitterEndpointSupport<T> extends MessageProducerSupport {
@@ -53,8 +54,6 @@ public abstract class AbstractInboundTwitterEndpointSupport<T> extends MessagePr
private volatile String metadataKey;
private volatile Properties lastPersistentEntry = new Properties();
protected volatile OAuthConfiguration configuration;
protected volatile long markerId = -1;
@@ -65,15 +64,9 @@ public abstract class AbstractInboundTwitterEndpointSupport<T> extends MessagePr
private volatile ScheduledFuture<?> twitterUpdatePollingTask;
private volatile String persistentIdentifier;
private final HistoryWritingMessagePostProcessor historyWritingPostProcessor = new HistoryWritingMessagePostProcessor();
public void setPersistentIdentifier(String persistentIdentifier) {
this.persistentIdentifier = persistentIdentifier;
}
public void setConfiguration(OAuthConfiguration configuration) {
this.configuration = configuration;
}
@@ -96,21 +89,22 @@ public abstract class AbstractInboundTwitterEndpointSupport<T> extends MessagePr
Assert.notNull(this.configuration, "'configuration' can't be null");
this.twitter = this.configuration.getTwitter();
Assert.notNull(this.twitter, "'twitter' instance can't be null");
metadataKey = this.getComponentType() + "@" + this.getComponentName()
+ "#" + this.configuration.getConsumerKey();
try {
if (StringUtils.hasText(this.persistentIdentifier)) {
if (this.metadataStore == null) {
logger.info("Creating FileBasedPropertiesStore");
metadataStore = new FileBasedPropertiesStore(this.persistentIdentifier);
((FileBasedPropertiesStore) metadataStore).afterPropertiesSet();
if (this.metadataStore == null) {
// first try to look for a 'messageStore' in the context
BeanFactory beanFactory = this.getBeanFactory();
if (beanFactory != null) {
MetadataStore metadataStore = IntegrationContextUtils.getMetadataStore(beanFactory);
if (metadataStore != null) {
this.metadataStore = metadataStore;
}
lastPersistentEntry = metadataStore.load();
}
if (this.metadataStore == null) {
this.metadataStore = new SimpleMetadataStore();
}
}
catch (Exception e) {
logger.warn("Failed to initialize and load from MetadataStore. Potential duplicates possible.", e);
}
Assert.hasText(this.getComponentName(), "Inbound Twitter adapter must have a name");
this.metadataKey = this.getComponentType() + "." + this.getComponentName()
+ "." + this.configuration.getConsumerKey();
}
protected void forwardAll(List<T> tResponses) {
@@ -154,7 +148,7 @@ public abstract class AbstractInboundTwitterEndpointSupport<T> extends MessagePr
else {
throw new IllegalArgumentException("Unsupported type of Twitter message: " + message.getClass());
}
String lastId = lastPersistentEntry.getProperty(this.metadataKey);
String lastId = this.metadataStore.get(this.metadataKey);
long lastTweetId = 0;
if (lastId != null) {
@@ -163,15 +157,12 @@ public abstract class AbstractInboundTwitterEndpointSupport<T> extends MessagePr
if (id > lastTweetId) {
sendMessage(twtMsg);
markLastStatusId(id);
if (metadataStore != null) {
metadataStore.write(this.lastPersistentEntry);
}
}
}
}
protected void markLastStatusId(long statusId) {
lastPersistentEntry.put(metadataKey, String.valueOf(statusId));
this.metadataStore.put(this.metadataKey, String.valueOf(statusId));
}
}

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.twitter.inbound;
import static junit.framework.Assert.assertEquals;
@@ -28,6 +29,7 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.twitter.oauth.OAuthConfiguration;
@@ -41,36 +43,18 @@ import twitter4j.Twitter;
/**
* @author Oleg Zhurakousky
*
*/
public class InboundDirectMessageStatusEndpointTests {
private DirectMessage firstMessage;
private DirectMessage secondMessage;
private Twitter twitter;
@Test
public void testTwitterMockedUpdates() throws Exception{
QueueChannel channel = new QueueChannel();
InboundDirectMessageEndpoint endpoint = new InboundDirectMessageEndpoint();
endpoint.setOutputChannel(channel);
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.afterPropertiesSet();
endpoint.setTaskScheduler(scheduler);
endpoint.setConfiguration(this.getTestConfigurationForDirectMessages());
endpoint.afterPropertiesSet();
endpoint.start();
Message message1 = channel.receive(3000);
assertNotNull(message1);
// should be second message since its timestamp is newer
assertEquals(secondMessage.getId(), ((DirectMessage)message1.getPayload()).getId());
Message message2 = channel.receive(100);
assertNull(message2); // should be null, since
}
@Before
public void prepare(){
public void prepare() {
twitter = mock(Twitter.class);
firstMessage = mock(DirectMessage.class);
when(firstMessage.getCreatedAt()).thenReturn(new Date(5555555555L));
@@ -79,27 +63,47 @@ public class InboundDirectMessageStatusEndpointTests {
when(secondMessage.getCreatedAt()).thenReturn(new Date(2222222222L));
when(secondMessage.getId()).thenReturn(2000);
}
@Test
public void testTwitterMockedUpdates() throws Exception{
QueueChannel channel = new QueueChannel();
InboundDirectMessageEndpoint endpoint = new InboundDirectMessageEndpoint();
endpoint.setOutputChannel(channel);
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.afterPropertiesSet();
endpoint.setTaskScheduler(scheduler);
endpoint.setConfiguration(this.getTestConfigurationForDirectMessages());
endpoint.setBeanName("twitterEndpoint");
endpoint.afterPropertiesSet();
endpoint.start();
Message<?> message1 = channel.receive(3000);
assertNotNull(message1);
// should be second message since its timestamp is newer
assertEquals(secondMessage.getId(), ((DirectMessage)message1.getPayload()).getId());
Message<?> message2 = channel.receive(100);
assertNull(message2); // should be null, since
}
@SuppressWarnings("unchecked")
private OAuthConfiguration getTestConfigurationForDirectMessages() throws Exception{
OAuthConfiguration configuration = mock(OAuthConfiguration.class);
RateLimitStatus rateLimitStatus = mock(RateLimitStatus.class);
when(twitter.getRateLimitStatus()).thenReturn(rateLimitStatus);
when(configuration.getTwitter()).thenReturn(twitter);
when(rateLimitStatus.getSecondsUntilReset()).thenReturn(2464);
when(rateLimitStatus.getRemainingHits()).thenReturn(250);
ResponseList<DirectMessage> responses = mock(ResponseList.class);
List<DirectMessage> testMessages = new ArrayList<DirectMessage>();
testMessages.add(firstMessage);
testMessages.add(secondMessage);
when(responses.iterator()).thenReturn(testMessages.iterator());
when(twitter.getDirectMessages()).thenReturn(responses);
when(twitter.getDirectMessages(Mockito.any(Paging.class))).thenReturn(responses);
return configuration;
}
}