From 42470f17b58a51c92f233676b4e6c5e3eb5354f1 Mon Sep 17 00:00:00 2001 From: william edwards Date: Wed, 13 Feb 2013 22:02:40 +0000 Subject: [PATCH 1/4] added retry around contentLength for testing --- .../java/ch/mbae/pusher/PusherChannel.java | 2 - .../HttpClientPusherTransportTest.java | 66 ++++++++++++------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/main/java/ch/mbae/pusher/PusherChannel.java b/src/main/java/ch/mbae/pusher/PusherChannel.java index 93d9fcf..f58e37a 100644 --- a/src/main/java/ch/mbae/pusher/PusherChannel.java +++ b/src/main/java/ch/mbae/pusher/PusherChannel.java @@ -31,7 +31,6 @@ public PusherChannel(String channelName, String pusherApplicationId, String push /** * Delivers a message to the Pusher API without providing a socket_id - * @param channel * @param event * @param jsonData * @return @@ -42,7 +41,6 @@ public PusherResponse pushEvent(String event, String jsonData) throws PusherTran /** * Delivers a message to the Pusher API - * @param channel * @param event * @param jsonData * @param socketId diff --git a/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java b/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java index 2da29e3..32b125a 100644 --- a/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java +++ b/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java @@ -9,6 +9,7 @@ import ch.mbae.pusher.PusherResponse; import junit.framework.Assert; import org.apache.log4j.Logger; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -32,9 +33,18 @@ public void setUp() { // create the transport under test this.tranportUnderTest = new HttpClientPusherTransport(); // the channel to inject the transport into - this.channel = new PusherChannel(CHANNEL, APPLICATION_ID, APPLICATION_KEY, APPLICATION_SECRET, this.tranportUnderTest); + this.channel = new PusherChannel(CHANNEL, + APPLICATION_ID, + APPLICATION_KEY, + APPLICATION_SECRET, + this.tranportUnderTest); } + @After + public void tearDown() { + this.tranportUnderTest = null; + this.channel = null; + } /** * Test of fetch method, of class HttpClientPusherTransport. */ @@ -42,17 +52,7 @@ public void setUp() { public void testFetch() throws Exception { // push the event PusherResponse response = this.channel.pushEvent(EVENT, JSON_STRING); - - LOGGER.debug(response.getResponseCode()); - LOGGER.debug(new String(response.getContent())); - LOGGER.debug(response.getHeaders().get("Content-Length")); - - // http status 202 - Assert.assertEquals(202, response.getResponseCode()); - // content as expected ? (hard test; might fail once) - //Assert.assertEquals("202 ACCEPTED\n", new String(response.getContent())); - // correct content length in http header? - Assert.assertEquals(Integer.valueOf(response.getHeaders().get("Content-Length")).intValue(), response.getContent().length); + retryAgainIfNecessary(response); } /** @@ -63,15 +63,37 @@ public void testFetchWidthSessionId() throws Exception { // push the event PusherResponse response = this.channel.pushEvent(EVENT, JSON_STRING, SOCKET_ID); - LOGGER.debug(response.getResponseCode()); - LOGGER.debug(new String(response.getContent())); - LOGGER.debug(response.getHeaders().get("Content-Length")); - - // http status 202 - Assert.assertEquals(202, response.getResponseCode()); - // content as expected ? (hard test; might fail once) - //Assert.assertEquals("202 ACCEPTED\n", new String(response.getContent())); - // correct content length in http header? - Assert.assertEquals(Integer.valueOf(response.getHeaders().get("Content-Length")).intValue(), response.getContent().length); + retryAgainIfNecessary(response); } + + private void retryAgainIfNecessary(PusherResponse response) throws Exception + { + if(!verifyContent(response)) + { + response = this.channel.pushEvent(EVENT, JSON_STRING, SOCKET_ID); + verifyContent(response); + } + + } + private boolean verifyContent(PusherResponse response) + { + LOGGER.debug(response.getResponseCode()); + LOGGER.debug(new String(response.getContent())); + LOGGER.debug(response.getHeaders().get("Content-Length")); + + Assert.assertEquals(202, response.getResponseCode()); + Assert.assertEquals(response.getHeaders().size(), 3); + + // content as expected ? (hard test; might fail once) + //Assert.assertEquals("202 ACCEPTED\n", new String(response.getContent())); + // correct content length in http header? + String contentLen = response.getHeaders().get("Content-Length"); + if(contentLen != null) + { + Assert.assertEquals(Integer.valueOf(response.getHeaders().get("Content-Length")).intValue(), response.getContent().length); + return true; + } + + return false; + } } From 5a7c83239193e9b50f9df99f9d248b080c1b226b Mon Sep 17 00:00:00 2001 From: william edwards Date: Thu, 14 Feb 2013 22:44:55 +0000 Subject: [PATCH 2/4] simplified code to use one set of credentials --- Pusher.java => src/main/java/Pusher.java | 44 ++++------------ .../main/java/PusherRequest.java | 0 src/main/java/ch/mbae/pusher/PushApi.java | 32 ++++++++++++ src/main/java/ch/mbae/pusher/PushImpl.java | 51 +++++++++++++++++++ .../java/ch/mbae/pusher/PusherChannel.java | 18 ++----- .../ch/mbae/pusher/PusherCredentials.java | 19 +++++++ .../ch/mbae/pusher/PusherChannelTest.java | 9 ++-- .../ch/mbae/pusher/PusherCredentials.java | 19 ------- .../HttpClientPusherTransportTest.java | 6 +-- 9 files changed, 124 insertions(+), 74 deletions(-) rename Pusher.java => src/main/java/Pusher.java (88%) rename PusherRequest.java => src/main/java/PusherRequest.java (100%) create mode 100644 src/main/java/ch/mbae/pusher/PushApi.java create mode 100644 src/main/java/ch/mbae/pusher/PushImpl.java create mode 100644 src/main/java/ch/mbae/pusher/PusherCredentials.java delete mode 100644 src/test/java/ch/mbae/pusher/PusherCredentials.java diff --git a/Pusher.java b/src/main/java/Pusher.java similarity index 88% rename from Pusher.java rename to src/main/java/Pusher.java index 59246aa..f909497 100644 --- a/Pusher.java +++ b/src/main/java/Pusher.java @@ -1,5 +1,9 @@ +import ch.mbae.pusher.PusherCredentials; +import com.google.appengine.api.urlfetch.*; +import org.apache.log4j.Logger; - +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; @@ -9,18 +13,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -import org.mortbay.log.Log; - -import com.google.appengine.api.urlfetch.HTTPHeader; -import com.google.appengine.api.urlfetch.HTTPMethod; -import com.google.appengine.api.urlfetch.HTTPRequest; -import com.google.appengine.api.urlfetch.HTTPResponse; -import com.google.appengine.api.urlfetch.URLFetchService; -import com.google.appengine.api.urlfetch.URLFetchServiceFactory; - /** * Static class to send messages to Pusher's REST API. * @@ -32,26 +24,12 @@ */ public class Pusher { + private static final Logger log = Logger.getLogger(Pusher.class); /** * Pusher Host name */ private final static String pusherHost = "api.pusherapp.com"; - /** - * Pusher Application Identifier - */ - private final static String pusherApplicationId = ""; - - /** - * Pusher Application Key - */ - private final static String pusherApplicationKey = ""; - - /** - * Pusher Secret - */ - private final static String pusherApplicationSecret = ""; - /** * Converts a byte array to a string representation * @param data @@ -92,10 +70,10 @@ private static String md5Representation(String data) { * @param data * @return */ - private static String hmacsha256Representation(String data) { + public static String hmacsha256Representation(String data) { try { // Create the HMAC/SHA256 key from application secret - final SecretKeySpec signingKey = new SecretKeySpec( pusherApplicationSecret.getBytes(), "HmacSHA256"); + final SecretKeySpec signingKey = new SecretKeySpec( PusherCredentials.APPLICATION_SECRET.getBytes(), "HmacSHA256"); // Create the message authentication code (MAC) final Mac mac = Mac.getInstance("HmacSHA256"); @@ -128,7 +106,7 @@ private static String buildQuery(String eventName, String jsonData, String socke StringBuffer buffer = new StringBuffer(); //Auth_Key buffer.append("auth_key="); - buffer.append(pusherApplicationKey); + buffer.append(PusherCredentials.APPLICATION_KEY); //Timestamp buffer.append("&auth_timestamp="); buffer.append(System.currentTimeMillis() / 1000); @@ -157,7 +135,7 @@ private static String buildURIPath(String channelName){ StringBuffer buffer = new StringBuffer(); //Application ID buffer.append("/apps/"); - buffer.append(pusherApplicationId); + buffer.append(PusherCredentials.APPLICATION_ID); //Channel name buffer.append("/channels/"); buffer.append(channelName); @@ -256,7 +234,7 @@ public static HTTPResponse triggerPush(String channel, String event, String json return urlFetchService.fetch(request); } catch (IOException e) { //Log warning - Log.warn("Pusher request could not be send to the following URI " + url.toString()); + log.warn("Pusher request could not be send to the following URI " + url.toString()); return null; } } diff --git a/PusherRequest.java b/src/main/java/PusherRequest.java similarity index 100% rename from PusherRequest.java rename to src/main/java/PusherRequest.java diff --git a/src/main/java/ch/mbae/pusher/PushApi.java b/src/main/java/ch/mbae/pusher/PushApi.java new file mode 100644 index 0000000..567bf3e --- /dev/null +++ b/src/main/java/ch/mbae/pusher/PushApi.java @@ -0,0 +1,32 @@ +package ch.mbae.pusher; + +/** + * Author: wge + * Date: 09/02/2013 + * Time: 18:55 + */ + +public interface PushApi +{ + /** + * The implementation must keep these secret. + * + * @param pusherApplicationId + * @param pusherApplicationKey + * @param pusherApplicationSecret + */ + void setGAECredentials(String pusherApplicationId, String pusherApplicationKey, String pusherApplicationSecret); + + /** + * + * @param channelName the particular channel + * @param eventName anything that describes your event. + * @param jsonData data to be pushed + * @param socketId + * @return A response object encapsulating all the headers from PusherApp.com + * @throws PusherTransportException + */ + PusherResponse pushEvent( String channelName, String eventName, String jsonData, String socketId) throws PusherTransportException; + + +} diff --git a/src/main/java/ch/mbae/pusher/PushImpl.java b/src/main/java/ch/mbae/pusher/PushImpl.java new file mode 100644 index 0000000..9e5bb06 --- /dev/null +++ b/src/main/java/ch/mbae/pusher/PushImpl.java @@ -0,0 +1,51 @@ +package ch.mbae.pusher;/** + * Author: wge + * Date: 14/02/2013 + * Time: 22:17 + */ + +import ch.mbae.pusher.transport.GAEPusherTransport; +import ch.mbae.pusher.transport.HttpClientPusherTransport; +import org.apache.log4j.Logger; + +import java.util.concurrent.ConcurrentHashMap; + +class PushImpl implements PushApi +{ + private static final Logger log = Logger.getLogger(PushImpl.class); + + @Override + public void setGAECredentials(String pusherApplicationId, String pusherApplicationKey, String pusherApplicationSecret) + { + } + + @Override + public PusherResponse pushEvent(String channelName, String eventName, String jsonData, String socketId) throws PusherTransportException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + private ConcurrentHashMap channelMap = new ConcurrentHashMap(); + + private PusherChannel findOrCreateHttpChannel(String channelName) + { + PusherChannel channel = channelMap.putIfAbsent(channelName,buildHttpChannel(channelName)); + return channel; + } + + private PusherChannel findOrCreateGAEChannel(String channelName) + { + PusherChannel channel = channelMap.putIfAbsent(channelName,buildGAEChannel(channelName)); + return channel; + } + + private PusherChannel buildGAEChannel(String channelName) + { + return new PusherChannel(channelName,new GAEPusherTransport()); + + } + private PusherChannel buildHttpChannel(String channelName) + { + return new PusherChannel(channelName,new HttpClientPusherTransport()); + } +} diff --git a/src/main/java/ch/mbae/pusher/PusherChannel.java b/src/main/java/ch/mbae/pusher/PusherChannel.java index f58e37a..38b6bf7 100644 --- a/src/main/java/ch/mbae/pusher/PusherChannel.java +++ b/src/main/java/ch/mbae/pusher/PusherChannel.java @@ -15,17 +15,9 @@ public class PusherChannel { private PusherTransport transport; private String channelName; - private String pusherApplicationId; - private String pusherApplicationSecret; - private String pusherApplicationKey; - - public PusherChannel(String channelName, String pusherApplicationId, String pusherApplicationKey, - String pusherApplicationSecret, PusherTransport transport) { - + + public PusherChannel(String channelName, PusherTransport transport) { this.channelName = channelName; - this.pusherApplicationKey = pusherApplicationKey; - this.pusherApplicationId = pusherApplicationId; - this.pusherApplicationSecret = pusherApplicationSecret; this.transport = transport; } @@ -48,11 +40,11 @@ public PusherResponse pushEvent(String event, String jsonData) throws PusherTran */ public PusherResponse pushEvent(String event, String jsonData, String socketId) throws PusherTransportException{ //Build URI path - String uriPath = PusherUtil.buildURIPath(this.channelName, this.pusherApplicationId); + String uriPath = PusherUtil.buildURIPath(this.channelName, PusherCredentials.APPLICATION_ID); //Build query - String query = PusherUtil.buildQuery(event, jsonData, socketId, this.pusherApplicationKey); + String query = PusherUtil.buildQuery(event, jsonData, socketId, PusherCredentials.APPLICATION_KEY); //Generate signature - String signature = PusherUtil.buildAuthenticationSignature(uriPath, query, this.pusherApplicationSecret); + String signature = PusherUtil.buildAuthenticationSignature(uriPath, query, PusherCredentials.APPLICATION_SECRET); //Build URI URL url = PusherUtil.buildURI(uriPath, query, signature); diff --git a/src/main/java/ch/mbae/pusher/PusherCredentials.java b/src/main/java/ch/mbae/pusher/PusherCredentials.java new file mode 100644 index 0000000..a9df9cb --- /dev/null +++ b/src/main/java/ch/mbae/pusher/PusherCredentials.java @@ -0,0 +1,19 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package ch.mbae.pusher; + +/** + * + * @author marcbaechinger + */ +public interface PusherCredentials +{ + String APPLICATION_ID = "37099"; + String APPLICATION_KEY = "e543b0af7cea4adfac24"; + String APPLICATION_SECRET = "cca824ca4792aa6a94b8"; + + String CHANNEL = "junit-test-channel"; + String EVENT = "junit-test-event"; +} diff --git a/src/test/java/ch/mbae/pusher/PusherChannelTest.java b/src/test/java/ch/mbae/pusher/PusherChannelTest.java index 016ce92..3985880 100644 --- a/src/test/java/ch/mbae/pusher/PusherChannelTest.java +++ b/src/test/java/ch/mbae/pusher/PusherChannelTest.java @@ -4,15 +4,16 @@ */ package ch.mbae.pusher; -import ch.mbae.pusher.transport.HttpClientPusherTransport; -import java.net.URL; import junit.framework.Assert; import org.apache.log4j.Logger; import org.easymock.Capture; -import static org.easymock.EasyMock.*; import org.junit.Before; import org.junit.Test; +import java.net.URL; + +import static org.easymock.EasyMock.*; + /** * * @author marcbaechinger @@ -31,7 +32,7 @@ public void setUp() { // create a mock for the transport this.transportMock = createMock(PusherTransport.class); // create the channel - this.testee = new PusherChannel(CHANNEL, APPLICATION_ID, APPLICATION_KEY, APPLICATION_SECRET, transportMock); + this.testee = new PusherChannel(CHANNEL, transportMock); } diff --git a/src/test/java/ch/mbae/pusher/PusherCredentials.java b/src/test/java/ch/mbae/pusher/PusherCredentials.java deleted file mode 100644 index 4d3561a..0000000 --- a/src/test/java/ch/mbae/pusher/PusherCredentials.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package ch.mbae.pusher; - -/** - * - * @author marcbaechinger - */ -public interface PusherCredentials { - - static final String APPLICATION_ID = ""; - static final String APPLICATION_KEY = ""; - static final String APPLICATION_SECRET = ""; - - static final String CHANNEL = "junit-test-channel"; - static final String EVENT = "junit-test-event"; -} diff --git a/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java b/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java index 32b125a..7b76218 100644 --- a/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java +++ b/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java @@ -33,11 +33,7 @@ public void setUp() { // create the transport under test this.tranportUnderTest = new HttpClientPusherTransport(); // the channel to inject the transport into - this.channel = new PusherChannel(CHANNEL, - APPLICATION_ID, - APPLICATION_KEY, - APPLICATION_SECRET, - this.tranportUnderTest); + this.channel = new PusherChannel(CHANNEL,this.tranportUnderTest); } @After From c2ffce25c9506141c12b1ed76e968096b71a3602 Mon Sep 17 00:00:00 2001 From: william edwards Date: Fri, 15 Feb 2013 16:17:39 +0000 Subject: [PATCH 3/4] made API --- README.md | 35 ++++------ src/main/java/ch/mbae/pusher/PushApi.java | 13 ++++ src/main/java/ch/mbae/pusher/PushImpl.java | 51 -------------- .../ch/mbae/pusher/PusherCredentials.java | 19 ------ .../ch/mbae/pusher/impl/CredentialHolder.java | 38 +++++++++++ .../java/ch/mbae/pusher/impl/PushImpl.java | 68 +++++++++++++++++++ .../mbae/pusher/{ => impl}/PusherChannel.java | 15 ++-- .../mbae/pusher/impl/PusherHelper.java} | 14 ++-- .../mbae/pusher/impl}/PusherRequest.java | 8 +-- .../transport/HttpClientPusherTransport.java | 29 +++----- src/main/resources/log4j.properties | 2 +- .../java/ch/mbae/pusher/PusherApiTest.java | 65 ++++++++++++++++++ .../ch/mbae/pusher/PusherChannelTest.java | 14 +++- .../java/ch/mbae/pusher/TestCredentials.java | 12 ++++ .../transport/GAEPusherTransportTest.java | 35 +++++----- .../HttpClientPusherTransportTest.java | 18 +++-- 16 files changed, 285 insertions(+), 151 deletions(-) delete mode 100644 src/main/java/ch/mbae/pusher/PushImpl.java delete mode 100644 src/main/java/ch/mbae/pusher/PusherCredentials.java create mode 100644 src/main/java/ch/mbae/pusher/impl/CredentialHolder.java create mode 100644 src/main/java/ch/mbae/pusher/impl/PushImpl.java rename src/main/java/ch/mbae/pusher/{ => impl}/PusherChannel.java (80%) rename src/main/java/{Pusher.java => ch/mbae/pusher/impl/PusherHelper.java} (95%) rename src/main/java/{ => ch/mbae/pusher/impl}/PusherRequest.java (88%) create mode 100644 src/test/java/ch/mbae/pusher/PusherApiTest.java create mode 100644 src/test/java/ch/mbae/pusher/TestCredentials.java diff --git a/README.md b/README.md index 06f0f0a..570e31c 100644 --- a/README.md +++ b/README.md @@ -5,34 +5,25 @@ This Java classes can be used to communicate very easily with the Pusher REST AP Get Started ----------- -Simply replace the Pusher specific constants in Pusher.java: +Use the PushApi as seen in ch.mbae.pusher.PushApi. - private final static String pusherApplicationId = ""; - - private final static String pusherApplicationKey = ""; - - private final static String pusherApplicationSecret = ""; - -Call one of the two available static methods called "triggerPush" and pass channel name, event name and the message body (JSON encoded data) as parameters: - - Pusher.triggerPush("test_channel", "my_event", jsonData); - -The second "triggerPush" method provides an additional parameter for the socket_id: + + PushApi api = new PushImpl(); - Pusher.triggerPush("test_channel", "my_event", jsonData, socketId); - -That's it. + api.setGAECredentials(pusherApplicationId, pusherApplicationKey, pusherApplicationSecret); + + then call the following, where all arguments are strings. + + PusherResponse resp = api.pushEvent( channelName, eventName, jsonData, socketId) ; -Default values --------------- -Sometimes it can be very convenient to prepulate a PusherRequest instance with default channel and/or event name: + The implementation caches your channels, therefore when you have finished, eg a disconnect happens, then + + api.disposeOfChannel(channelName); - PusherRequest p = new PusherRequest("test_channel","my_event"); -To send a request to the Pusher API just call "triggerPush" on this instance: +That's it. - p.triggerPush(jsondata); License ------- -Copyright 2010, Stephan Scheuermann. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php \ No newline at end of file +Copyright 2010, Stephan Scheuermann. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php diff --git a/src/main/java/ch/mbae/pusher/PushApi.java b/src/main/java/ch/mbae/pusher/PushApi.java index 567bf3e..d59399b 100644 --- a/src/main/java/ch/mbae/pusher/PushApi.java +++ b/src/main/java/ch/mbae/pusher/PushApi.java @@ -1,5 +1,7 @@ package ch.mbae.pusher; +import java.util.Collection; + /** * Author: wge * Date: 09/02/2013 @@ -28,5 +30,16 @@ public interface PushApi */ PusherResponse pushEvent( String channelName, String eventName, String jsonData, String socketId) throws PusherTransportException; + /** + * Should be called when we have finished using a channel. + * For example, a disconnection has occurred. + * @param channelName + */ + void disposeOfChannel(String channelName); + /** + * Show all the channels currently being used + * @return + */ + Collection listLiveChannels(); } diff --git a/src/main/java/ch/mbae/pusher/PushImpl.java b/src/main/java/ch/mbae/pusher/PushImpl.java deleted file mode 100644 index 9e5bb06..0000000 --- a/src/main/java/ch/mbae/pusher/PushImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package ch.mbae.pusher;/** - * Author: wge - * Date: 14/02/2013 - * Time: 22:17 - */ - -import ch.mbae.pusher.transport.GAEPusherTransport; -import ch.mbae.pusher.transport.HttpClientPusherTransport; -import org.apache.log4j.Logger; - -import java.util.concurrent.ConcurrentHashMap; - -class PushImpl implements PushApi -{ - private static final Logger log = Logger.getLogger(PushImpl.class); - - @Override - public void setGAECredentials(String pusherApplicationId, String pusherApplicationKey, String pusherApplicationSecret) - { - } - - @Override - public PusherResponse pushEvent(String channelName, String eventName, String jsonData, String socketId) throws PusherTransportException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - private ConcurrentHashMap channelMap = new ConcurrentHashMap(); - - private PusherChannel findOrCreateHttpChannel(String channelName) - { - PusherChannel channel = channelMap.putIfAbsent(channelName,buildHttpChannel(channelName)); - return channel; - } - - private PusherChannel findOrCreateGAEChannel(String channelName) - { - PusherChannel channel = channelMap.putIfAbsent(channelName,buildGAEChannel(channelName)); - return channel; - } - - private PusherChannel buildGAEChannel(String channelName) - { - return new PusherChannel(channelName,new GAEPusherTransport()); - - } - private PusherChannel buildHttpChannel(String channelName) - { - return new PusherChannel(channelName,new HttpClientPusherTransport()); - } -} diff --git a/src/main/java/ch/mbae/pusher/PusherCredentials.java b/src/main/java/ch/mbae/pusher/PusherCredentials.java deleted file mode 100644 index a9df9cb..0000000 --- a/src/main/java/ch/mbae/pusher/PusherCredentials.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package ch.mbae.pusher; - -/** - * - * @author marcbaechinger - */ -public interface PusherCredentials -{ - String APPLICATION_ID = "37099"; - String APPLICATION_KEY = "e543b0af7cea4adfac24"; - String APPLICATION_SECRET = "cca824ca4792aa6a94b8"; - - String CHANNEL = "junit-test-channel"; - String EVENT = "junit-test-event"; -} diff --git a/src/main/java/ch/mbae/pusher/impl/CredentialHolder.java b/src/main/java/ch/mbae/pusher/impl/CredentialHolder.java new file mode 100644 index 0000000..2bea1cd --- /dev/null +++ b/src/main/java/ch/mbae/pusher/impl/CredentialHolder.java @@ -0,0 +1,38 @@ +package ch.mbae.pusher.impl;/** + * Author: wge + * Date: 15/02/2013 + * Time: 12:54 + */ + +public class CredentialHolder +{ + private static final CredentialHolder instance = new CredentialHolder(); + + private String APPLICATION_ID; + private String APPLICATION_KEY; + private String APPLICATION_SECRET; + + public static String getAPPLICATION_ID() + { + return instance.APPLICATION_ID; + } + + public static String getAPPLICATION_KEY() + { + return instance.APPLICATION_KEY; + } + + public static String getAPPLICATION_SECRET() + { + return instance.APPLICATION_SECRET; + } + + public static synchronized void build (String application_id, String application_key, String application_secret) + { + instance.APPLICATION_ID = application_id; + instance.APPLICATION_KEY = application_key; + instance.APPLICATION_SECRET = application_secret; + } + + +} diff --git a/src/main/java/ch/mbae/pusher/impl/PushImpl.java b/src/main/java/ch/mbae/pusher/impl/PushImpl.java new file mode 100644 index 0000000..f92fdef --- /dev/null +++ b/src/main/java/ch/mbae/pusher/impl/PushImpl.java @@ -0,0 +1,68 @@ +package ch.mbae.pusher.impl;/** + * Author: wge + * Date: 14/02/2013 + * Time: 22:17 + */ + +import ch.mbae.pusher.*; +import ch.mbae.pusher.transport.HttpClientPusherTransport; +import org.apache.log4j.Logger; + +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; + +public class PushImpl implements PushApi +{ + private static final Logger log = Logger.getLogger(PushImpl.class); + private ConcurrentHashMap channelMap = new ConcurrentHashMap(); + + @Override + public void setGAECredentials(String pusherApplicationId, String pusherApplicationKey, String pusherApplicationSecret) + { + CredentialHolder.build(pusherApplicationId,pusherApplicationKey,pusherApplicationSecret); + } + + @Override + public PusherResponse pushEvent(String channelName, String eventName, String jsonData, String socketId) throws PusherTransportException + { + PusherChannel channel = findOrCreateHttpChannel(channelName); + + return channel.pushEvent(eventName, jsonData, socketId); + + } + + @Override + public void disposeOfChannel(String channelName) + { + PusherChannel channel = channelMap.get(channelName); + + if(channel != null) + { + channelMap.remove(channelName); + log.info("channel " + channelName + " successfully removed "); + } + else + { + log.warn("channel " + channelName + " not found "); + } + } + + @Override + public Collection listLiveChannels() + { + return channelMap.keySet(); + } + + private PusherChannel findOrCreateHttpChannel(String channelName) + { + PusherChannel channel = channelMap.get(channelName); + if(channel == null) + { + channel = new PusherChannel(channelName,new HttpClientPusherTransport()); + channelMap.putIfAbsent(channelName,channel); + } + return channel; + } + + +} diff --git a/src/main/java/ch/mbae/pusher/PusherChannel.java b/src/main/java/ch/mbae/pusher/impl/PusherChannel.java similarity index 80% rename from src/main/java/ch/mbae/pusher/PusherChannel.java rename to src/main/java/ch/mbae/pusher/impl/PusherChannel.java index 38b6bf7..68eef8c 100644 --- a/src/main/java/ch/mbae/pusher/PusherChannel.java +++ b/src/main/java/ch/mbae/pusher/impl/PusherChannel.java @@ -2,9 +2,13 @@ * Author: marcbaechinger * Copyright 2011. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php */ -package ch.mbae.pusher; +package ch.mbae.pusher.impl; +import ch.mbae.pusher.PusherResponse; +import ch.mbae.pusher.PusherTransport; +import ch.mbae.pusher.PusherTransportException; import ch.mbae.pusher.util.PusherUtil; + import java.net.URL; /** @@ -27,7 +31,8 @@ public PusherChannel(String channelName, PusherTransport transport) { * @param jsonData * @return */ - public PusherResponse pushEvent(String event, String jsonData) throws PusherTransportException{ + public PusherResponse pushEvent(String event, String jsonData) throws PusherTransportException + { return pushEvent(event, jsonData, ""); } @@ -40,11 +45,11 @@ public PusherResponse pushEvent(String event, String jsonData) throws PusherTran */ public PusherResponse pushEvent(String event, String jsonData, String socketId) throws PusherTransportException{ //Build URI path - String uriPath = PusherUtil.buildURIPath(this.channelName, PusherCredentials.APPLICATION_ID); + String uriPath = PusherUtil.buildURIPath(this.channelName, CredentialHolder.getAPPLICATION_ID()); //Build query - String query = PusherUtil.buildQuery(event, jsonData, socketId, PusherCredentials.APPLICATION_KEY); + String query = PusherUtil.buildQuery(event, jsonData, socketId, CredentialHolder.getAPPLICATION_KEY()); //Generate signature - String signature = PusherUtil.buildAuthenticationSignature(uriPath, query, PusherCredentials.APPLICATION_SECRET); + String signature = PusherUtil.buildAuthenticationSignature(uriPath, query, CredentialHolder.getAPPLICATION_SECRET()); //Build URI URL url = PusherUtil.buildURI(uriPath, query, signature); diff --git a/src/main/java/Pusher.java b/src/main/java/ch/mbae/pusher/impl/PusherHelper.java similarity index 95% rename from src/main/java/Pusher.java rename to src/main/java/ch/mbae/pusher/impl/PusherHelper.java index f909497..3b68b97 100644 --- a/src/main/java/Pusher.java +++ b/src/main/java/ch/mbae/pusher/impl/PusherHelper.java @@ -1,4 +1,5 @@ -import ch.mbae.pusher.PusherCredentials; +package ch.mbae.pusher.impl; + import com.google.appengine.api.urlfetch.*; import org.apache.log4j.Logger; @@ -22,9 +23,10 @@ * @author Stephan Scheuermann * Copyright 2010. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php */ -public class Pusher { +class PusherHelper +{ - private static final Logger log = Logger.getLogger(Pusher.class); + private static final Logger log = Logger.getLogger(PusherHelper.class); /** * Pusher Host name */ @@ -73,7 +75,7 @@ private static String md5Representation(String data) { public static String hmacsha256Representation(String data) { try { // Create the HMAC/SHA256 key from application secret - final SecretKeySpec signingKey = new SecretKeySpec( PusherCredentials.APPLICATION_SECRET.getBytes(), "HmacSHA256"); + final SecretKeySpec signingKey = new SecretKeySpec( CredentialHolder.getAPPLICATION_SECRET().getBytes(), "HmacSHA256"); // Create the message authentication code (MAC) final Mac mac = Mac.getInstance("HmacSHA256"); @@ -106,7 +108,7 @@ private static String buildQuery(String eventName, String jsonData, String socke StringBuffer buffer = new StringBuffer(); //Auth_Key buffer.append("auth_key="); - buffer.append(PusherCredentials.APPLICATION_KEY); + buffer.append(CredentialHolder.getAPPLICATION_KEY()); //Timestamp buffer.append("&auth_timestamp="); buffer.append(System.currentTimeMillis() / 1000); @@ -135,7 +137,7 @@ private static String buildURIPath(String channelName){ StringBuffer buffer = new StringBuffer(); //Application ID buffer.append("/apps/"); - buffer.append(PusherCredentials.APPLICATION_ID); + buffer.append(CredentialHolder.getAPPLICATION_ID()); //Channel name buffer.append("/channels/"); buffer.append(channelName); diff --git a/src/main/java/PusherRequest.java b/src/main/java/ch/mbae/pusher/impl/PusherRequest.java similarity index 88% rename from src/main/java/PusherRequest.java rename to src/main/java/ch/mbae/pusher/impl/PusherRequest.java index 99c06b2..c79908b 100644 --- a/src/main/java/PusherRequest.java +++ b/src/main/java/ch/mbae/pusher/impl/PusherRequest.java @@ -1,4 +1,4 @@ - +package ch.mbae.pusher.impl; import com.google.appengine.api.urlfetch.HTTPResponse; @@ -46,7 +46,7 @@ public PusherRequest(String channelName, String eventName) { * @return */ public HTTPResponse triggerPush(String jsonData){ - return Pusher.triggerPush(channelName, eventName, jsonData); + return PusherHelper.triggerPush(channelName, eventName, jsonData); } /** @@ -56,7 +56,7 @@ public HTTPResponse triggerPush(String jsonData){ * @return */ public HTTPResponse triggerPush(String jsonData, String eventName){ - return Pusher.triggerPush(channelName, eventName, jsonData); + return PusherHelper.triggerPush(channelName, eventName, jsonData); } /** @@ -67,7 +67,7 @@ public HTTPResponse triggerPush(String jsonData, String eventName){ * @return */ public HTTPResponse triggerPush(String jsonData, String eventName, String socketId){ - return Pusher.triggerPush(channelName, eventName, jsonData, socketId); + return PusherHelper.triggerPush(channelName, eventName, jsonData, socketId); } public void setEventName(String eventName) { diff --git a/src/main/java/ch/mbae/pusher/transport/HttpClientPusherTransport.java b/src/main/java/ch/mbae/pusher/transport/HttpClientPusherTransport.java index fb06579..32f7f29 100644 --- a/src/main/java/ch/mbae/pusher/transport/HttpClientPusherTransport.java +++ b/src/main/java/ch/mbae/pusher/transport/HttpClientPusherTransport.java @@ -4,48 +4,41 @@ */ package ch.mbae.pusher.transport; -import ch.mbae.pusher.PusherTransport; import ch.mbae.pusher.PusherResponse; +import ch.mbae.pusher.PusherTransport; import ch.mbae.pusher.PusherTransportException; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpPost; -import org.apache.http.conn.ClientConnectionManager; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + /** * Implementation of PusherTransport using Jakarta HttpClient * @author marcbaechinger */ public class HttpClientPusherTransport implements PusherTransport { - DefaultHttpClient httpClient; + DefaultHttpClient httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager()); /** - * create a http transportn using a single http client + * create a http transport using a single http client * for all requests */ public HttpClientPusherTransport() { - ClientConnectionManager cm = new ThreadSafeClientConnManager(); - - this.httpClient = new DefaultHttpClient(cm); - this.httpClient.getParams().setParameter( - CoreProtocolPNames.PROTOCOL_VERSION, - HttpVersion.HTTP_1_1); // set default to HTTP 1.1 - this.httpClient.getParams().setParameter( - CoreProtocolPNames.HTTP_CONTENT_CHARSET, - "UTF-8"); + this.httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); // set default to HTTP 1.1 + this.httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET,"UTF-8"); } @Override diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties index d947a7e..3073f55 100644 --- a/src/main/resources/log4j.properties +++ b/src/main/resources/log4j.properties @@ -6,4 +6,4 @@ log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n # Print only messages of level WARN or above in the package com.foo. -log4j.logger.com.foo=WARN \ No newline at end of file +log4j.logger.ch.mbae.pusher=WARN \ No newline at end of file diff --git a/src/test/java/ch/mbae/pusher/PusherApiTest.java b/src/test/java/ch/mbae/pusher/PusherApiTest.java new file mode 100644 index 0000000..ddc8b66 --- /dev/null +++ b/src/test/java/ch/mbae/pusher/PusherApiTest.java @@ -0,0 +1,65 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package ch.mbae.pusher; + +import ch.mbae.pusher.impl.PushImpl; +import ch.mbae.pusher.transport.HttpClientPusherTransportTest; +import org.apache.log4j.Logger; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; + +/** + * + * @author William Edwards + */ +public class PusherApiTest +{ + + private static final Logger LOGGER = Logger.getLogger(PusherApiTest.class); + + private static final String JSON_STRING = "{ originator: " + PusherApiTest.class.getName() + "}"; + + private PushApi api; + + @Before + public void setUp() { + api = new PushImpl(); + } + + @Test + public void pushTest() + { + api.setGAECredentials(TestCredentials.APPLICATION_ID,TestCredentials.APPLICATION_KEY,TestCredentials.APPLICATION_SECRET); + + try + { + PusherResponse response = api.pushEvent("company-001","create",JSON_STRING,"987"); + + assert(response != null); + + HttpClientPusherTransportTest.verifyContent(response); + + + Collection existingChannels = api.listLiveChannels(); + + assert(existingChannels.size() == 1); + + existingChannels.iterator().next().equals("company-001"); + + api.disposeOfChannel("company-001"); + + assert(api.listLiveChannels().size() == 0); + + } + catch (PusherTransportException e) + { + LOGGER.error(e.getMessage()); + } + } + + +} diff --git a/src/test/java/ch/mbae/pusher/PusherChannelTest.java b/src/test/java/ch/mbae/pusher/PusherChannelTest.java index 3985880..db6daa0 100644 --- a/src/test/java/ch/mbae/pusher/PusherChannelTest.java +++ b/src/test/java/ch/mbae/pusher/PusherChannelTest.java @@ -4,6 +4,8 @@ */ package ch.mbae.pusher; +import ch.mbae.pusher.impl.CredentialHolder; +import ch.mbae.pusher.impl.PusherChannel; import junit.framework.Assert; import org.apache.log4j.Logger; import org.easymock.Capture; @@ -18,7 +20,7 @@ * * @author marcbaechinger */ -public class PusherChannelTest implements PusherCredentials { +public class PusherChannelTest { private static final Logger LOGGER = Logger.getLogger(PusherChannelTest.class); @@ -26,9 +28,15 @@ public class PusherChannelTest implements PusherCredentials { private PusherChannel testee; private PusherTransport transportMock; - + + String CHANNEL = "junit-test-channel"; + String EVENT = "junit-test-event"; + @Before public void setUp() { + + CredentialHolder.build(TestCredentials.APPLICATION_ID, TestCredentials.APPLICATION_KEY, TestCredentials.APPLICATION_SECRET); + // create a mock for the transport this.transportMock = createMock(PusherTransport.class); // create the channel @@ -37,7 +45,7 @@ public void setUp() { /** - * Test o f pushEvent method, of class PusherChannel. + * Test of pushEvent method, of class PusherChannel. */ @Test public void testPushEvent_String_String() throws PusherTransportException { diff --git a/src/test/java/ch/mbae/pusher/TestCredentials.java b/src/test/java/ch/mbae/pusher/TestCredentials.java new file mode 100644 index 0000000..a684da6 --- /dev/null +++ b/src/test/java/ch/mbae/pusher/TestCredentials.java @@ -0,0 +1,12 @@ +package ch.mbae.pusher;/** + * Author: wge + * Date: 15/02/2013 + * Time: 14:37 + * Ensure these are wired to the Test Application, not production. + */ +public interface TestCredentials +{ + String APPLICATION_ID = "37099"; + String APPLICATION_KEY = "e543b0af7cea4adfac24"; + String APPLICATION_SECRET = "cca824ca4792aa6a94b8"; +} diff --git a/src/test/java/ch/mbae/pusher/transport/GAEPusherTransportTest.java b/src/test/java/ch/mbae/pusher/transport/GAEPusherTransportTest.java index 697fcae..30a68ea 100644 --- a/src/test/java/ch/mbae/pusher/transport/GAEPusherTransportTest.java +++ b/src/test/java/ch/mbae/pusher/transport/GAEPusherTransportTest.java @@ -4,9 +4,10 @@ */ package ch.mbae.pusher.transport; -import ch.mbae.pusher.PusherChannel; -import ch.mbae.pusher.PusherCredentials; -import org.junit.After; +import ch.mbae.pusher.impl.PusherChannel; +import ch.mbae.pusher.PusherResponse; +import ch.mbae.pusher.PusherTransportException; +import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -15,29 +16,31 @@ * * @author marcbaechinger */ -public class GAEPusherTransportTest implements PusherCredentials { +public class GAEPusherTransportTest { private PusherChannel channel; - - - - + private static final Logger log = Logger.getLogger(GAEPusherTransportTest.class); + @Before public void setUp() { - this.channel = new PusherChannel("gae", PusherCredentials.APPLICATION_ID, - PusherCredentials.APPLICATION_KEY, PusherCredentials.APPLICATION_SECRET, - new GAEPusherTransport()); + this.channel = new PusherChannel("gae",new GAEPusherTransport()); } - @After - public void tearDown() { - } /** * Test of fetch method, of class GAEPusherTransport. */ @Test @Ignore - public void testFetch() throws Exception { - channel.pushEvent("gae-event", "{'transport': 'GAE'}"); + public void testFetch() + { + try + { + PusherResponse response = channel.pushEvent("gae-event", "{'transport': 'GAE'}"); + int x = 2; + } + catch (PusherTransportException e) + { + log.error(e.getMessage()); + } } } diff --git a/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java b/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java index 7b76218..3bc7432 100644 --- a/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java +++ b/src/test/java/ch/mbae/pusher/transport/HttpClientPusherTransportTest.java @@ -4,9 +4,10 @@ */ package ch.mbae.pusher.transport; -import ch.mbae.pusher.PusherChannel; -import ch.mbae.pusher.PusherCredentials; import ch.mbae.pusher.PusherResponse; +import ch.mbae.pusher.TestCredentials; +import ch.mbae.pusher.impl.CredentialHolder; +import ch.mbae.pusher.impl.PusherChannel; import junit.framework.Assert; import org.apache.log4j.Logger; import org.junit.After; @@ -18,7 +19,7 @@ * * @author marcbaechinger */ -public class HttpClientPusherTransportTest implements PusherCredentials { +public class HttpClientPusherTransportTest { private static final Logger LOGGER = Logger.getLogger(HttpClientPusherTransportTest.class); @@ -27,9 +28,13 @@ public class HttpClientPusherTransportTest implements PusherCredentials { private HttpClientPusherTransport tranportUnderTest; private PusherChannel channel; - + String CHANNEL = "junit-test-channel"; + String EVENT = "junit-test-event"; + @Before public void setUp() { + + CredentialHolder.build(TestCredentials.APPLICATION_ID, TestCredentials.APPLICATION_KEY, TestCredentials.APPLICATION_SECRET); // create the transport under test this.tranportUnderTest = new HttpClientPusherTransport(); // the channel to inject the transport into @@ -55,7 +60,7 @@ public void testFetch() throws Exception { * Test of fetch method, of class HttpClientPusherTransport. */ @Test - public void testFetchWidthSessionId() throws Exception { + public void testFetchWidthSocketId() throws Exception { // push the event PusherResponse response = this.channel.pushEvent(EVENT, JSON_STRING, SOCKET_ID); @@ -71,7 +76,8 @@ private void retryAgainIfNecessary(PusherResponse response) throws Exception } } - private boolean verifyContent(PusherResponse response) + + public static boolean verifyContent(PusherResponse response) { LOGGER.debug(response.getResponseCode()); LOGGER.debug(new String(response.getContent())); From 5181858a7c40729e10c6f6c6c6977a091d9aa59b Mon Sep 17 00:00:00 2001 From: william edwards Date: Fri, 15 Feb 2013 16:37:19 +0000 Subject: [PATCH 4/4] added test scope --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index df9077f..5001e17 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ org.easymock easymock 3.0 + test org.apache.httpcomponents