INT-1527 MetadataStore refactoring
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user