Java tutorial
/** * Mule PubSubHubbub Connector * * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.module.pubsubhubbub; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.StringReader; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.lang.StringUtils; import org.junit.Rule; import org.mule.DefaultMuleMessage; import org.mule.api.MuleMessage; import org.mule.module.pubsubhubbub.data.DataStore; import org.mule.module.pubsubhubbub.data.TopicSubscription; import org.mule.tck.functional.CountdownCallback; import org.mule.tck.functional.FunctionalTestComponent; import org.mule.tck.junit4.FunctionalTestCase; import org.mule.tck.junit4.rule.DynamicPort; import org.mule.transport.http.HttpConstants; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.io.SyndFeedInput; public abstract class AbstractPuSHTestCase extends FunctionalTestCase { protected static final String TEST_TOPIC = "http://mulesoft.org/fake-topic"; @Rule public DynamicPort hubPort = new DynamicPort("port1"); @Rule public DynamicPort subscriberPort = new DynamicPort("port2"); @Rule public DynamicPort publisherPort = new DynamicPort("port3"); protected HttpClient httpClient; protected DataStore dataStore; protected FunctionalTestComponent publisherFTC; protected CountdownCallback publisherCC; protected FunctionalTestComponent subscriberFTC; protected CountdownCallback subscriberCC; @Override protected void doSetUp() throws Exception { dataStore = muleContext.getRegistry().lookupObject(PuSHHubModule.class).getDataStore(); httpClient = new HttpClient(); super.doSetUp(); } protected int getHubPort() { return hubPort.getNumber(); } protected int getSubscriberCallbacksPort() { return subscriberPort.getNumber(); } protected int getPublisherPort() { return publisherPort.getNumber(); } protected String getMouthTestTopic() { return "http://localhost:" + getPublisherPort() + "/feeds/mouth/rss"; } protected String getBocaTestTopic() { return "http://localhost:" + getPublisherPort() + "/feeds/boca/rss"; } protected void setupSubscriberFTC(final String flowName, final int messagesExpected) throws Exception { subscriberFTC = getFunctionalTestComponent(flowName); subscriberCC = new CountdownCallback(messagesExpected); subscriberFTC.setEventCallback(subscriberCC); } protected void setupPublisherFTC(final int messagesExpected) throws Exception { publisherFTC = getFunctionalTestComponent("publisher"); publisherCC = new CountdownCallback(messagesExpected); publisherFTC.setEventCallback(publisherCC); } protected void checkTopicSubscriptionStored(final String callback, final Map<String, List<String>> subscriptionRequest) throws Exception { for (final String hubTopic : subscriptionRequest.get("hub.topic")) { final URI hubTopicUri = new URI(hubTopic); final Set<TopicSubscription> topicSubscriptions = ponderUntilSubscriptionStored(hubTopicUri); assertEquals(1, topicSubscriptions.size()); final TopicSubscription topicSubscription = topicSubscriptions.iterator().next(); assertEquals(hubTopicUri, topicSubscription.getTopicUrl()); assertEquals(new URI(callback), topicSubscription.getCallbackUrl()); assertTrue(topicSubscription.getExpiryTime() > 0L); final String secretAsString = subscriptionRequest.get("hub.secret") != null ? subscriptionRequest.get("hub.secret").get(0) : null; if (StringUtils.isNotBlank(secretAsString)) { assertTrue(Arrays.equals(secretAsString.getBytes("utf-8"), topicSubscription.getSecret())); } else { assertNull(topicSubscription.getSecret()); } } } protected void checkTopicSubscriptionCleared(final String callback, final Map<String, List<String>> subscriptionRequest) throws Exception { for (final String hubTopic : subscriptionRequest.get("hub.topic")) { final URI hubTopicUri = new URI(hubTopic); final Set<TopicSubscription> topicSubscriptions = dataStore.getTopicSubscriptions(hubTopicUri); assertEquals(0, topicSubscriptions.size()); } } protected Set<TopicSubscription> ponderUntilSubscriptionStored(final URI hubTopicUri) throws InterruptedException { for (int attempts = 0; attempts < 300; attempts++) { final Set<TopicSubscription> topicSubscriptions = dataStore.getTopicSubscriptions(hubTopicUri); if (!topicSubscriptions.isEmpty()) { return topicSubscriptions; } Thread.sleep(100L); } return Collections.emptySet(); } protected void doTestSuccessfullNewContentNotificationAndContentFetch(final String topicUrl) throws Exception { doNotifyHubOfNewContent(topicUrl); publisherCC.await(TimeUnit.SECONDS.toMillis(getTestTimeoutSecs())); assertTrue(topicUrl.contains((String) publisherFTC.getLastReceivedMessage())); } protected void doNotifyHubOfNewContent(final String topicUrl) throws Exception { final Map<String, String> subscriptionRequest = new HashMap<String, String>(); subscriptionRequest.put("hub.mode", "publish"); subscriptionRequest.put("hub.url", topicUrl); final MuleMessage response = wrapAndSendRequestToHub(subscriptionRequest); assertEquals("204", response.getInboundProperty("http.status")); } protected MuleMessage wrapAndSendRequestToHub(final Map<String, String> subscriptionRequest) throws Exception { final Map<String, List<String>> wrappedRequest = new HashMap<String, List<String>>(); for (final Entry<String, String> param : subscriptionRequest.entrySet()) { wrappedRequest.put(param.getKey(), Collections.singletonList(param.getValue())); } return sendRequestToHub(wrappedRequest); } protected MuleMessage sendRequestToHub(final Map<String, List<String>> subscriptionRequest) throws Exception { return sendRequestToHub(subscriptionRequest, "application/x-www-form-urlencoded"); } protected MuleMessage sendRequestToHub(final Map<String, List<String>> subscriptionRequest, final String contentType) throws Exception { final String hubUrl = "http://localhost:" + getHubPort() + "/hub"; final PostMethod postMethod = new PostMethod(hubUrl); postMethod.setRequestHeader(HttpConstants.HEADER_CONTENT_TYPE, contentType); for (final Entry<String, List<String>> param : subscriptionRequest.entrySet()) { for (final String value : param.getValue()) { postMethod.addParameter(param.getKey(), value); } } final Integer responseStatus = httpClient.executeMethod(postMethod); final MuleMessage response = new DefaultMuleMessage(postMethod.getResponseBodyAsString(), Collections.singletonMap("http.status", (Object) responseStatus.toString()), null, null, muleContext); return response; } protected void doTestSuccessfulContentDistribution(final String topicUrl) throws Exception { doTestSuccessfullNewContentNotificationAndContentFetch(topicUrl); // check RSS content has been pushed to callback FTC subscriberCC.await(TimeUnit.SECONDS.toMillis(getTestTimeoutSecs())); final SyndFeed syndFeed = new SyndFeedInput(true) .build(new StringReader((String) subscriberFTC.getLastReceivedMessage())); assertEquals("rss_2.0", syndFeed.getFeedType()); } protected void ensureSubscribed(final String topicUrl) throws InterruptedException, URISyntaxException { final Set<TopicSubscription> stored = ponderUntilSubscriptionStored(new URI(topicUrl)); assertThat(stored.size(), is(1)); } }